Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
moab::DataCoupler Class Reference

This class couples data between meshes. More...

#include <DataCoupler.hpp>

+ Collaboration diagram for moab::DataCoupler:

Public Types

enum  Method { CONSTANT , LINEAR_FE , QUADRATIC_FE , SPECTRAL }
 
enum  IntegType { VOLUME }
 

Public Member Functions

 DataCoupler (Interface *impl, Range &source_ents, int coupler_id, ParallelComm *pc=NULL, bool init_locator=true, int dim=-1)
 
virtual ~DataCoupler ()
 
ErrorCode locate_points (double *xyz, int num_points, const double rel_iter_tol=1.0e-10, const double abs_iter_tol=1.0e-10, const double inside_tol=1.0e-6)
 
ErrorCode locate_points (Range &ents, const double rel_iter_tol=1.0e-10, const double abs_iter_tol=1.0e-10, const double inside_tol=1.0e-6)
 
ErrorCode interpolate (int method, Tag tag, double *interp_vals=NULL, std::vector< int > *point_indices=NULL, bool normalize=true)
 
ErrorCode interpolate (int method, const std::string &tag_name, double *interp_vals=NULL, std::vector< int > *point_indices=NULL, bool normalize=true)
 
ErrorCode interpolate (int *methods, const std::string *tag_names, int *points_per_method, int num_methods, double *interp_vals=NULL, std::vector< int > *point_indices=NULL, bool normalize=true)
 
ErrorCode interpolate (int *methods, Tag *tag_names, int *points_per_method, int num_methods, double *interp_vals=NULL, std::vector< int > *point_indices=NULL, bool normalize=true)
 
SpatialLocatorspatial_locator ()
 
int my_id () const
 
const Rangetarget_ents () const
 
Rangetarget_ents ()
 
int get_dim () const
 

Private Attributes

InterfacembImpl
 
ParallelCommmyPcomm
 
SpatialLocatormyLocator
 
int myId
 
Range targetEnts
 
int myDim
 

Detailed Description

This class couples data between meshes.

The coupler interpolates solution data at a set of points. Data being interpolated resides on a "source" mesh, in a tag or in vertex coords. Applications calling this coupler send in entities, and receive back data interpolated at those points. Entities in the source mesh containing those points do not have to reside on the same processor.

To use, an application should:

  • instantiate this DataCoupler by calling the constructor collectively on all processors in the communicator
  • call locate_points, which locates the points to be interpolated and (optionally) caches the results in this class and SpatialLocator
  • call interpolate, which does the interpolation

Multiple interpolations (of multiple tags, or element-average vs. true interpolation) can be done after locating the points.

SpatialLocator is used for the spatial location portion of this work.

This class is a next-generation implementation of Coupler.

Definition at line 39 of file DataCoupler.hpp.

Member Enumeration Documentation

◆ IntegType

Enumerator
VOLUME 

Definition at line 50 of file DataCoupler.hpp.

51  {
52  VOLUME
53  };

◆ Method

Enumerator
CONSTANT 
LINEAR_FE 
QUADRATIC_FE 
SPECTRAL 

Definition at line 42 of file DataCoupler.hpp.

43  {
44  CONSTANT,
45  LINEAR_FE,
47  SPECTRAL
48  };

Constructor & Destructor Documentation

◆ DataCoupler()

moab::DataCoupler::DataCoupler ( Interface impl,
Range source_ents,
int  coupler_id,
ParallelComm pc = NULL,
bool  init_locator = true,
int  dim = -1 
)

Definition at line 22 of file DataCoupler.cpp.

28  : mbImpl( impl ), myPcomm( pc ), myId( coupler_id ), myDim( dim )
29 {
30  assert( NULL != mbImpl && ( myPcomm || !source_ents.empty() ) );
31 
32  // Now initialize the tree
33  if( init_locator )
34  {
35  myLocator = new SpatialLocator( mbImpl, source_ents );
36  myLocator->elem_eval( new ElemEvaluator( mbImpl ) );
37 
38  // Initialize element evaluator with the default for the entity types in source_ents;
39  // can be replaced later by application if desired
40  if( !source_ents.empty() )
41  {
42  Range::pair_iterator pit = source_ents.pair_begin();
43  EntityType last_type = MBMAXTYPE;
44  for( ; pit != source_ents.pair_end(); ++pit )
45  {
46  EntityType this_type = mbImpl->type_from_handle( pit->first );
47  if( last_type == this_type ) continue;
48  ErrorCode rval = myLocator->elem_eval()->set_eval_set( pit->first );
49  if( MB_SUCCESS != rval ) throw( rval );
50  last_type = this_type;
51  }
52  }
53  }
54 
55  if( -1 == dim && !source_ents.empty() ) myDim = mbImpl->dimension_from_handle( *source_ents.rbegin() );
56 }

References dim, moab::Interface::dimension_from_handle(), moab::SpatialLocator::elem_eval(), moab::Range::empty(), ErrorCode, MB_SUCCESS, mbImpl, MBMAXTYPE, myDim, myLocator, myPcomm, moab::Range::pair_begin(), moab::Range::pair_end(), moab::Range::rbegin(), moab::ElemEvaluator::set_eval_set(), and moab::Interface::type_from_handle().

◆ ~DataCoupler()

moab::DataCoupler::~DataCoupler ( )
virtual

Definition at line 60 of file DataCoupler.cpp.

61 {
62  delete myLocator->elem_eval();
63  delete myLocator;
64 }

References moab::SpatialLocator::elem_eval(), and myLocator.

Member Function Documentation

◆ get_dim()

int moab::DataCoupler::get_dim ( ) const
inline

Definition at line 236 of file DataCoupler.hpp.

237  {
238  return myDim;
239  }

References myDim.

◆ interpolate() [1/4]

ErrorCode moab::DataCoupler::interpolate ( int *  methods,
const std::string *  tag_names,
int *  points_per_method,
int  num_methods,
double *  interp_vals = NULL,
std::vector< int > *  point_indices = NULL,
bool  normalize = true 
)

◆ interpolate() [2/4]

ErrorCode moab::DataCoupler::interpolate ( int *  methods,
Tag tag_names,
int *  points_per_method,
int  num_methods,
double *  interp_vals = NULL,
std::vector< int > *  point_indices = NULL,
bool  normalize = true 
)

Method‍/ int method = methods[TLob.vi_rd[4*i + 3]];

Definition at line 109 of file DataCoupler.cpp.

116 {
117  // Lowest-level interpolate function, does actual interpolation using calls to ElemEvaluator
118 
119  ErrorCode result = MB_SUCCESS;
120 
121  unsigned int pts_total = 0;
122  for( int i = 0; i < num_methods; i++ )
123  pts_total += ( points_per_method ? points_per_method[i] : targetEnts.size() );
124 
125  unsigned int num_indices = ( point_indices ? point_indices->size() : targetEnts.size() );
126  // # points and indices should be identical
127  if( pts_total != num_indices ) return MB_FAILURE;
128 
129  // Since each tuple contains one interpolated tag, if we're interpolating multiple tags, every
130  // tuple needs to be able to store up to max tag size
131  int max_tsize = -1;
132  for( int i = 0; i < num_methods; i++ )
133  {
134  int tmp_tsize;
135  result = mbImpl->tag_get_length( tags[i], tmp_tsize );
136  if( MB_SUCCESS != result ) return MB_FAILURE;
137  max_tsize = std::max( max_tsize, tmp_tsize );
138  }
139 
140  if( myPcomm && myPcomm->size() > 1 )
141  {
142  // Build up the tuple list to distribute from my target points; assume that
143  // all procs use same method/tag input
144  TupleList TLob; // TLob structure: (pto_i, ridx_i, lidx_i, meth_tagidx_i)
145  TLob.initialize( 4, 0, 0, 0, num_indices );
146  int tn = 0; // The tuple number we're currently on
147  TLob.enableWriteAccess();
148  for( int m = 0; m < num_methods; m++ )
149  {
150  int num_points = ( points_per_method ? points_per_method[m] : targetEnts.size() );
151  for( int j = 0; j < num_points; j++ )
152  {
153  int idx = ( point_indices ? ( *point_indices )[j]
154  : j ); // The index in my targetEnts for this interpolation point
155 
156  // Remote proc/idx from myLocator->parLocTable
157  TLob.vi_wr[4 * tn] = myLocator->par_loc_table().vi_rd[2 * idx]; // proc
158  TLob.vi_wr[4 * tn + 1] = myLocator->par_loc_table().vi_rd[2 * idx + 1]; // Remote idx
159 
160  // Local entity index, tag/method index from my data
161  TLob.vi_wr[4 * tn + 2] = idx;
162  TLob.vi_wr[4 * tn + 3] = m;
163  TLob.inc_n();
164  tn++;
165  }
166  }
167 
168  // Scatter/gather interpolation points
169  myPcomm->proc_config().crystal_router()->gs_transfer( 1, TLob, 0 );
170 
171  // Perform interpolation on local source mesh; put results into TLinterp
172  TupleList TLinterp; // TLinterp structure: (pto_i, ridx_i, vals[max_tsize]_d)
173  TLinterp.initialize( 2, 0, 0, max_tsize, TLob.get_n() );
174  TLinterp.set_n( TLob.get_n() ); // Set the size right away
175  TLinterp.enableWriteAccess();
176 
177  for( unsigned int i = 0; i < TLob.get_n(); i++ )
178  {
179  int lidx = TLob.vi_rd[4 * i + 1]; // Index into myLocator's local table
180  // Method and tag indexed with same index
181  ///*Method*/ int method = methods[TLob.vi_rd[4*i + 3]];
182  Tag tag = tags[TLob.vi_rd[4 * i + 3]];
183  // Copy proc/remote index from TLob
184  TLinterp.vi_wr[2 * i] = TLob.vi_rd[4 * i];
185  TLinterp.vi_wr[2 * i + 1] = TLob.vi_rd[4 * i + 2];
186 
187  // Set up the evaluator for the tag and entity, then interpolate, putting result in
188  // TLinterp
191  result =
192  myLocator->elem_eval()->eval( myLocator->loc_table().vr_rd + 3 * lidx, TLinterp.vr_rd + i * max_tsize );
193  if( MB_SUCCESS != result ) return result;
194  }
195 
196  // Scatter/gather interpolation data
197  myPcomm->proc_config().crystal_router()->gs_transfer( 1, TLinterp, 0 );
198 
199  // Copy the interpolated field as a unit
200  std::copy( TLinterp.vr_rd, TLinterp.vr_rd + TLinterp.get_n() * max_tsize, interp_vals );
201  }
202  else
203  {
204  // If called serially, interpolate directly from local locations/entities,
205  // into either interp_vals or by setting data directly on tags on those entities
206  std::vector< double > tmp_vals;
207  std::vector< EntityHandle > tmp_ents;
208  double* tmp_dbl = interp_vals;
209  for( int i = 0; i < num_methods; i++ )
210  {
211  int num_points = ( points_per_method ? points_per_method[i] : targetEnts.size() );
212 
213  // Interpolated data is tsize long, which is either max size (if data passed back to
214  // caller in interp_vals) or tag size (if data will be set on entities, in which case it
215  // shouldn't have padding) set sizes here, inside loop over methods, to reduce memory
216  // usage
217  int tsize = max_tsize, tsize_bytes = 0;
218  if( !interp_vals )
219  {
220  tmp_vals.resize( num_points * max_tsize );
221  tmp_dbl = &tmp_vals[0];
222  tmp_ents.resize( num_points );
223  result = mbImpl->tag_get_length( tags[i], tsize );
224  if( MB_SUCCESS != result ) return result;
225  result = mbImpl->tag_get_bytes( tags[i], tsize_bytes );
226  if( MB_SUCCESS != result ) return result;
227  }
228 
229  for( int j = 0; j < num_points; j++ )
230  {
231  int lidx;
232  if( point_indices )
233  lidx = ( *point_indices )[j];
234  else
235  lidx = j;
236 
237  myLocator->elem_eval()->set_tag_handle( tags[i] );
239  if( !interp_vals ) tmp_ents[j] = targetEnts[lidx]; // Could be performance-sensitive, thus the if test
240  result = myLocator->elem_eval()->eval( myLocator->loc_table().vr_rd + 3 * lidx, tmp_dbl );
241  tmp_dbl += tsize;
242  if( MB_SUCCESS != result ) return result;
243  } // for j over points
244 
245  if( !interp_vals )
246  {
247  // Set tags on tmp_ents; data is already w/o padding, due to tsize setting above
248  result = mbImpl->tag_set_data( tags[i], &tmp_ents[0], tmp_ents.size(), &tmp_vals[0] );
249  if( MB_SUCCESS != result ) return result;
250  }
251 
252  } // for i over methods
253  } // if myPcomm
254 
255  // Done
256  return MB_SUCCESS;
257 }

References moab::ProcConfig::crystal_router(), moab::SpatialLocator::elem_eval(), moab::TupleList::enableWriteAccess(), ErrorCode, moab::ElemEvaluator::eval(), moab::TupleList::get_n(), moab::TupleList::inc_n(), moab::TupleList::initialize(), moab::SpatialLocator::loc_table(), MB_SUCCESS, mbImpl, myLocator, myPcomm, moab::SpatialLocator::par_loc_table(), moab::ParallelComm::proc_config(), moab::ElemEvaluator::set_ent_handle(), moab::TupleList::set_n(), moab::ElemEvaluator::set_tag_handle(), moab::Range::size(), moab::ParallelComm::size(), moab::Interface::tag_get_bytes(), moab::Interface::tag_get_length(), moab::Interface::tag_set_data(), targetEnts, moab::TupleList::vi_rd, moab::TupleList::vi_wr, moab::TupleList::vr_rd, and moab::TupleList::vul_rd.

◆ interpolate() [3/4]

ErrorCode moab::DataCoupler::interpolate ( int  method,
const std::string &  tag_name,
double *  interp_vals = NULL,
std::vector< int > *  point_indices = NULL,
bool  normalize = true 
)

Definition at line 95 of file DataCoupler.cpp.

100 {
101  // Tag name input, translate to tag handle and pass down the chain
102 
103  Tag tag;
104  ErrorCode result = mbImpl->tag_get_handle( interp_tag.c_str(), tag );MB_CHK_SET_ERR( result, "Failed to get handle for interpolation tag \"" << interp_tag << "\"" );
105 
106  return interpolate( method, tag, interp_vals, point_indices, normalize );
107 }

References ErrorCode, interpolate(), MB_CHK_SET_ERR, mbImpl, normalize(), and moab::Interface::tag_get_handle().

◆ interpolate() [4/4]

ErrorCode moab::DataCoupler::interpolate ( int  method,
Tag  tag,
double *  interp_vals = NULL,
std::vector< int > *  point_indices = NULL,
bool  normalize = true 
)
inline

Definition at line 266 of file DataCoupler.hpp.

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 }

References normalize(), moab::Range::size(), and targetEnts.

Referenced by DeformMeshRemap::execute(), and interpolate().

◆ locate_points() [1/2]

ErrorCode moab::DataCoupler::locate_points ( double *  xyz,
int  num_points,
const double  rel_iter_tol = 1.0e-10,
const double  abs_iter_tol = 1.0e-10,
const double  inside_tol = 1.0e-6 
)

Definition at line 81 of file DataCoupler.cpp.

86 {
87 #ifdef MOAB_HAVE_MPI
88  if( myPcomm && myPcomm->size() > 1 )
89  return myLocator->par_locate_points( myPcomm, xyz, num_points, rel_iter_tol, abs_iter_tol, inside_tol );
90 #endif
91 
92  return myLocator->locate_points( xyz, num_points, rel_iter_tol, abs_iter_tol, inside_tol );
93 }

References moab::SpatialLocator::locate_points(), myLocator, myPcomm, and moab::ParallelComm::size().

Referenced by DeformMeshRemap::execute().

◆ locate_points() [2/2]

ErrorCode moab::DataCoupler::locate_points ( Range ents,
const double  rel_iter_tol = 1.0e-10,
const double  abs_iter_tol = 1.0e-10,
const double  inside_tol = 1.0e-6 
)

Definition at line 66 of file DataCoupler.cpp.

70 {
71  targetEnts = targ_ents;
72 
73 #ifdef MOAB_HAVE_MPI
74  if( myPcomm && myPcomm->size() > 1 )
75  return myLocator->par_locate_points( myPcomm, targ_ents, rel_iter_tol, abs_iter_tol, inside_tol );
76 #endif
77 
78  return myLocator->locate_points( targ_ents, rel_iter_tol, abs_iter_tol, inside_tol );
79 }

References moab::SpatialLocator::locate_points(), myLocator, myPcomm, moab::ParallelComm::size(), and targetEnts.

◆ my_id()

int moab::DataCoupler::my_id ( ) const
inline

Definition at line 224 of file DataCoupler.hpp.

225  {
226  return myId;
227  }

References myId.

◆ spatial_locator()

SpatialLocator* moab::DataCoupler::spatial_locator ( )
inline

Definition at line 220 of file DataCoupler.hpp.

221  {
222  return myLocator;
223  }

References myLocator.

Referenced by DeformMeshRemap::execute().

◆ target_ents() [1/2]

Range& moab::DataCoupler::target_ents ( )
inline

Definition at line 232 of file DataCoupler.hpp.

233  {
234  return targetEnts;
235  }

References targetEnts.

◆ target_ents() [2/2]

const Range& moab::DataCoupler::target_ents ( ) const
inline

Definition at line 228 of file DataCoupler.hpp.

229  {
230  return targetEnts;
231  }

References targetEnts.

Member Data Documentation

◆ mbImpl

Interface* moab::DataCoupler::mbImpl
private

Definition at line 244 of file DataCoupler.hpp.

Referenced by DataCoupler(), and interpolate().

◆ myDim

int moab::DataCoupler::myDim
private

Definition at line 263 of file DataCoupler.hpp.

Referenced by DataCoupler(), and get_dim().

◆ myId

int moab::DataCoupler::myId
private

Definition at line 256 of file DataCoupler.hpp.

Referenced by my_id().

◆ myLocator

SpatialLocator* moab::DataCoupler::myLocator
private

◆ myPcomm

ParallelComm* moab::DataCoupler::myPcomm
private

Definition at line 248 of file DataCoupler.hpp.

Referenced by DataCoupler(), interpolate(), and locate_points().

◆ targetEnts

Range moab::DataCoupler::targetEnts
private

Definition at line 260 of file DataCoupler.hpp.

Referenced by interpolate(), locate_points(), and target_ents().


The documentation for this class was generated from the following files: