MOAB: Mesh Oriented datABase
(version 5.4.1)
|
This class couples data between meshes. More...
#include <DataCoupler.hpp>
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) |
SpatialLocator * | spatial_locator () |
int | my_id () const |
const Range & | target_ents () const |
Range & | target_ents () |
int | get_dim () const |
Private Attributes | |
Interface * | mbImpl |
ParallelComm * | myPcomm |
SpatialLocator * | myLocator |
int | myId |
Range | targetEnts |
int | myDim |
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:
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.
Definition at line 42 of file DataCoupler.hpp.
{ CONSTANT, LINEAR_FE, QUADRATIC_FE, SPECTRAL };
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.
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().
: mbImpl( impl ), myPcomm( pc ), myId( coupler_id ), myDim( dim ) { assert( NULL != mbImpl && ( myPcomm || !source_ents.empty() ) ); // Now initialize the tree if( init_locator ) { myLocator = new SpatialLocator( mbImpl, source_ents ); myLocator->elem_eval( new ElemEvaluator( mbImpl ) ); // Initialize element evaluator with the default for the entity types in source_ents; // can be replaced later by application if desired if( !source_ents.empty() ) { Range::pair_iterator pit = source_ents.pair_begin(); EntityType last_type = MBMAXTYPE; for( ; pit != source_ents.pair_end(); ++pit ) { EntityType this_type = mbImpl->type_from_handle( pit->first ); if( last_type == this_type ) continue; ErrorCode rval = myLocator->elem_eval()->set_eval_set( pit->first ); if( MB_SUCCESS != rval ) throw( rval ); last_type = this_type; } } } if( -1 == dim && !source_ents.empty() ) myDim = mbImpl->dimension_from_handle( *source_ents.rbegin() ); }
moab::DataCoupler::~DataCoupler | ( | ) | [virtual] |
Definition at line 60 of file DataCoupler.cpp.
References moab::SpatialLocator::elem_eval(), and myLocator.
int moab::DataCoupler::get_dim | ( | ) | const [inline] |
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.
References moab::Range::size(), and targetEnts.
Referenced by DeformMeshRemap::execute(), and interpolate().
{ // No point indices input, int num_pts = ( point_indices ? point_indices->size() : targetEnts.size() ); return interpolate( &method, &tag, &num_pts, 1, interp_vals, point_indices, normalize ); }
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.
References ErrorCode, interpolate(), MB_CHK_SET_ERR, mbImpl, and moab::Interface::tag_get_handle().
{ // Tag name input, translate to tag handle and pass down the chain Tag tag; 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 << "\"" ); return interpolate( method, tag, interp_vals, point_indices, normalize ); }
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 |
||
) |
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.
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.
{ // Lowest-level interpolate function, does actual interpolation using calls to ElemEvaluator ErrorCode result = MB_SUCCESS; unsigned int pts_total = 0; for( int i = 0; i < num_methods; i++ ) pts_total += ( points_per_method ? points_per_method[i] : targetEnts.size() ); unsigned int num_indices = ( point_indices ? point_indices->size() : targetEnts.size() ); // # points and indices should be identical if( pts_total != num_indices ) return MB_FAILURE; // Since each tuple contains one interpolated tag, if we're interpolating multiple tags, every // tuple needs to be able to store up to max tag size int max_tsize = -1; for( int i = 0; i < num_methods; i++ ) { int tmp_tsize; result = mbImpl->tag_get_length( tags[i], tmp_tsize ); if( MB_SUCCESS != result ) return MB_FAILURE; max_tsize = std::max( max_tsize, tmp_tsize ); } if( myPcomm && myPcomm->size() > 1 ) { // Build up the tuple list to distribute from my target points; assume that // all procs use same method/tag input TupleList TLob; // TLob structure: (pto_i, ridx_i, lidx_i, meth_tagidx_i) TLob.initialize( 4, 0, 0, 0, num_indices ); int tn = 0; // The tuple number we're currently on TLob.enableWriteAccess(); for( int m = 0; m < num_methods; m++ ) { int num_points = ( points_per_method ? points_per_method[m] : targetEnts.size() ); for( int j = 0; j < num_points; j++ ) { int idx = ( point_indices ? ( *point_indices )[j] : j ); // The index in my targetEnts for this interpolation point // Remote proc/idx from myLocator->parLocTable TLob.vi_wr[4 * tn] = myLocator->par_loc_table().vi_rd[2 * idx]; // proc TLob.vi_wr[4 * tn + 1] = myLocator->par_loc_table().vi_rd[2 * idx + 1]; // Remote idx // Local entity index, tag/method index from my data TLob.vi_wr[4 * tn + 2] = idx; TLob.vi_wr[4 * tn + 3] = m; TLob.inc_n(); tn++; } } // Scatter/gather interpolation points myPcomm->proc_config().crystal_router()->gs_transfer( 1, TLob, 0 ); // Perform interpolation on local source mesh; put results into TLinterp TupleList TLinterp; // TLinterp structure: (pto_i, ridx_i, vals[max_tsize]_d) TLinterp.initialize( 2, 0, 0, max_tsize, TLob.get_n() ); TLinterp.set_n( TLob.get_n() ); // Set the size right away TLinterp.enableWriteAccess(); for( unsigned int i = 0; i < TLob.get_n(); i++ ) { int lidx = TLob.vi_rd[4 * i + 1]; // Index into myLocator's local table // Method and tag indexed with same index ///*Method*/ int method = methods[TLob.vi_rd[4*i + 3]]; Tag tag = tags[TLob.vi_rd[4 * i + 3]]; // Copy proc/remote index from TLob TLinterp.vi_wr[2 * i] = TLob.vi_rd[4 * i]; TLinterp.vi_wr[2 * i + 1] = TLob.vi_rd[4 * i + 2]; // Set up the evaluator for the tag and entity, then interpolate, putting result in // TLinterp myLocator->elem_eval()->set_tag_handle( tag ); myLocator->elem_eval()->set_ent_handle( myLocator->loc_table().vul_rd[lidx] ); result = myLocator->elem_eval()->eval( myLocator->loc_table().vr_rd + 3 * lidx, TLinterp.vr_rd + i * max_tsize ); if( MB_SUCCESS != result ) return result; } // Scatter/gather interpolation data myPcomm->proc_config().crystal_router()->gs_transfer( 1, TLinterp, 0 ); // Copy the interpolated field as a unit std::copy( TLinterp.vr_rd, TLinterp.vr_rd + TLinterp.get_n() * max_tsize, interp_vals ); } else { // If called serially, interpolate directly from local locations/entities, // into either interp_vals or by setting data directly on tags on those entities std::vector< double > tmp_vals; std::vector< EntityHandle > tmp_ents; double* tmp_dbl = interp_vals; for( int i = 0; i < num_methods; i++ ) { int num_points = ( points_per_method ? points_per_method[i] : targetEnts.size() ); // Interpolated data is tsize long, which is either max size (if data passed back to // caller in interp_vals) or tag size (if data will be set on entities, in which case it // shouldn't have padding) set sizes here, inside loop over methods, to reduce memory // usage int tsize = max_tsize, tsize_bytes = 0; if( !interp_vals ) { tmp_vals.resize( num_points * max_tsize ); tmp_dbl = &tmp_vals[0]; tmp_ents.resize( num_points ); result = mbImpl->tag_get_length( tags[i], tsize ); if( MB_SUCCESS != result ) return result; result = mbImpl->tag_get_bytes( tags[i], tsize_bytes ); if( MB_SUCCESS != result ) return result; } for( int j = 0; j < num_points; j++ ) { int lidx; if( point_indices ) lidx = ( *point_indices )[j]; else lidx = j; myLocator->elem_eval()->set_tag_handle( tags[i] ); myLocator->elem_eval()->set_ent_handle( myLocator->loc_table().vul_rd[lidx] ); if( !interp_vals ) tmp_ents[j] = targetEnts[lidx]; // Could be performance-sensitive, thus the if test result = myLocator->elem_eval()->eval( myLocator->loc_table().vr_rd + 3 * lidx, tmp_dbl ); tmp_dbl += tsize; if( MB_SUCCESS != result ) return result; } // for j over points if( !interp_vals ) { // Set tags on tmp_ents; data is already w/o padding, due to tsize setting above result = mbImpl->tag_set_data( tags[i], &tmp_ents[0], tmp_ents.size(), &tmp_vals[0] ); if( MB_SUCCESS != result ) return result; } } // for i over methods } // if myPcomm // Done return MB_SUCCESS; }
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.
References moab::SpatialLocator::locate_points(), myLocator, myPcomm, and moab::ParallelComm::size().
Referenced by DeformMeshRemap::execute().
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.
References moab::SpatialLocator::locate_points(), myLocator, myPcomm, moab::ParallelComm::size(), and targetEnts.
{ targetEnts = targ_ents; #ifdef MOAB_HAVE_MPI if( myPcomm && myPcomm->size() > 1 ) return myLocator->par_locate_points( myPcomm, targ_ents, rel_iter_tol, abs_iter_tol, inside_tol ); #endif return myLocator->locate_points( targ_ents, rel_iter_tol, abs_iter_tol, inside_tol ); }
int moab::DataCoupler::my_id | ( | ) | const [inline] |
SpatialLocator* moab::DataCoupler::spatial_locator | ( | ) | [inline] |
Definition at line 220 of file DataCoupler.hpp.
References myLocator.
Referenced by DeformMeshRemap::execute().
{ return myLocator; }
const Range& moab::DataCoupler::target_ents | ( | ) | const [inline] |
Range& moab::DataCoupler::target_ents | ( | ) | [inline] |
Interface* moab::DataCoupler::mbImpl [private] |
Definition at line 244 of file DataCoupler.hpp.
Referenced by DataCoupler(), and interpolate().
int moab::DataCoupler::myDim [private] |
Definition at line 263 of file DataCoupler.hpp.
Referenced by DataCoupler(), and get_dim().
int moab::DataCoupler::myId [private] |
Definition at line 256 of file DataCoupler.hpp.
Referenced by my_id().
SpatialLocator* moab::DataCoupler::myLocator [private] |
Definition at line 252 of file DataCoupler.hpp.
Referenced by DataCoupler(), interpolate(), locate_points(), spatial_locator(), and ~DataCoupler().
ParallelComm* moab::DataCoupler::myPcomm [private] |
Definition at line 248 of file DataCoupler.hpp.
Referenced by DataCoupler(), interpolate(), and locate_points().
Range moab::DataCoupler::targetEnts [private] |
Definition at line 260 of file DataCoupler.hpp.
Referenced by interpolate(), locate_points(), and target_ents().