Mesh Oriented datABase  (version 5.6.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 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 110 of file DataCoupler.cpp.

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

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 );
105  MB_CHK_SET_ERR( result, "Failed to get handle for interpolation tag \"" << interp_tag << "\"" );
106 
107  return interpolate( method, tag, interp_vals, point_indices, normalize );
108 }

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: