//---------------------------------------------------------------------------// // Test that we can remember a value and check it with DBC. TEUCHOS_UNIT_TEST( DataTransferKitException, remember_test ) { DTK_REMEMBER( int test_value_1 = 0 ); DTK_REMEMBER( int test_value_2 = 1 ); try { DTK_CHECK( test_value_1 ); } catch( const DataTransferKit::DataTransferKitException& assertion ) { #if HAVE_DTK_DBC TEST_ASSERT( 1 ); #else TEST_ASSERT( 0 ); #endif } catch( ... ) { #if HAVE_DTK_DBC TEST_ASSERT( 0 ); #endif } try { DTK_CHECK( test_value_2 ); TEST_ASSERT( 1 ); } catch( ... ) { TEST_ASSERT( 0 ); } }
Teuchos::Array<double> CloudDomain<2>::center() const { DTK_CHECK( d_bounds[0] <= d_bounds[1] ); DTK_CHECK( d_bounds[2] <= d_bounds[3] ); Teuchos::Array<double> center( 2 ); center[0] = (d_bounds[1]+d_bounds[0]) / 2.0; center[1] = (d_bounds[3]+d_bounds[2]) / 2.0; return center; }
bool CloudDomain<2>::pointInDomain( const Teuchos::ArrayView<const double>& coords ) const { DTK_REQUIRE( coords.size() == 2 ); DTK_CHECK( d_bounds[0] <= d_bounds[1] ); DTK_CHECK( d_bounds[2] <= d_bounds[3] ); return ( coords[0] >= d_bounds[0] && coords[0] <= d_bounds[1] && coords[1] >= d_bounds[2] && coords[1] <= d_bounds[3] ) ? true : false; }
//---------------------------------------------------------------------------// // Create the function space. void STKMeshManager::createFunctionSpace( const BasisType basis_type, const PredicateFunction& select_function ) { Teuchos::RCP<EntitySet> entity_set = Teuchos::rcp( new STKMeshEntitySet(d_bulk_data) ); Teuchos::RCP<EntityLocalMap> local_map = Teuchos::rcp( new STKMeshEntityLocalMap(d_bulk_data) ); Teuchos::RCP<EntityShapeFunction> shape_function; switch( basis_type ) { case BASIS_TYPE_GRADIENT: shape_function = Teuchos::rcp( new STKMeshNodalShapeFunction(d_bulk_data) ); break; default: bool bad_basis_type = true; DTK_INSIST( !bad_basis_type ); break; } DTK_CHECK( Teuchos::nonnull(shape_function) ); Teuchos::RCP<EntityIntegrationRule> integration_rule = Teuchos::rcp( new STKMeshEntityIntegrationRule(d_bulk_data) ); d_function_space = Teuchos::rcp( new FunctionSpace(entity_set,local_map,shape_function, integration_rule,select_function) ); DTK_ENSURE( Teuchos::nonnull(d_function_space) ); }
/*! * \brief Find the set of entities a point neighbors. */ void CoarseLocalSearch::search( const Teuchos::ArrayView<const double>& point, const Teuchos::ParameterList& parameters, Teuchos::Array<Entity>& neighbors ) const { // Find the leaf of nearest neighbors. int num_neighbors = 100; if ( parameters.isParameter("Coarse Local Search kNN") ) { num_neighbors = parameters.get<int>("Coarse Local Search kNN"); } num_neighbors = std::min( num_neighbors, Teuchos::as<int>(d_entity_map.size()) ); Teuchos::Array<unsigned> local_neighbors = d_tree->nnSearch( point, num_neighbors ); // Extract the neighbors. neighbors.resize( local_neighbors.size() ); Teuchos::Array<unsigned>::const_iterator local_it; Teuchos::Array<Entity>::iterator entity_it; for ( local_it = local_neighbors.begin(), entity_it = neighbors.begin(); local_it != local_neighbors.end(); ++local_it, ++entity_it ) { DTK_CHECK( d_entity_map.count(*local_it) ); *entity_it = d_entity_map.find(*local_it)->second; } }
//---------------------------------------------------------------------------// // Test the invariant check for DBC. TEUCHOS_UNIT_TEST( DataTransferKitException, invariant_test ) { try { DTK_CHECK( 0 ); throw std::runtime_error( "this shouldn't be thrown" ); } catch( const DataTransferKit::DataTransferKitException& assertion ) { #if HAVE_DTK_DBC std::string message( assertion.what() ); std::string true_message( "DataTransferKit DataTransferKitException: 0, failed in" ); std::string::size_type idx = message.find( true_message ); if ( idx == std::string::npos ) { TEST_ASSERT( 0 ); } #else TEST_ASSERT( 0 ); #endif } catch( ... ) { #if HAVE_DTK_DBC TEST_ASSERT( 0 ); #endif } }
void CloudDomain<2>::expand( const double radius ) { DTK_CHECK( radius >= 0.0 ); d_bounds[0] -= radius; d_bounds[1] += radius; d_bounds[2] -= radius; d_bounds[3] += radius; }
//---------------------------------------------------------------------------// // Given a local support id and a dimension, read data from the application // field. double LibmeshVariableField::readFieldData( const SupportId support_id, const int dimension ) const { DTK_REQUIRE( 0 == dimension ); const libMesh::Node& node = d_libmesh_mesh->node( support_id ); DTK_CHECK( 1 == node.n_comp(d_system_id,d_variable_id) ); libMesh::dof_id_type dof_id = node.dof_number(d_system_id,d_variable_id,0); return d_libmesh_system->current_local_solution->el( dof_id ); }
//---------------------------------------------------------------------------// // Return the Cartesian bounding box around an entity. void STKMeshEntityImpl::boundingBox( Teuchos::Tuple<double,6>& bounds ) const { DTK_REQUIRE( Teuchos::nonnull(d_bulk_data) ); Intrepid::FieldContainer<double> node_coords = STKMeshHelpers::getEntityNodeCoordinates( Teuchos::Array<stk::mesh::Entity>(1,d_extra_data->d_stk_entity), *d_bulk_data ); DTK_CHECK( node_coords.rank() == 3 ); DTK_CHECK( node_coords.dimension(0) == 1 ); double max = std::numeric_limits<double>::max(); bounds = Teuchos::tuple( max, max, max, -max, -max, -max ); Teuchos::Array<stk::mesh::Entity>::const_iterator entity_node_it; for ( int n = 0; n < node_coords.dimension(1); ++n ) { for ( int d = 0; d < node_coords.dimension(2); ++d ) { bounds[d] = std::min( bounds[d], node_coords(0,n,d) ); bounds[d+3] = std::max( bounds[d+3], node_coords(0,n,d) ); } } }
BoundingBox GeometryManager<Geometry,GlobalOrdinal>::localBoundingBox() const { double global_x_min = Teuchos::ScalarTraits<double>::rmax(); double global_y_min = Teuchos::ScalarTraits<double>::rmax(); double global_z_min = Teuchos::ScalarTraits<double>::rmax(); double global_x_max = -Teuchos::ScalarTraits<double>::rmax(); double global_y_max = -Teuchos::ScalarTraits<double>::rmax(); double global_z_max = -Teuchos::ScalarTraits<double>::rmax(); // Get the local bounding boxes compute the local bounding box. BoundingBox local_box; Teuchos::Tuple<double,6> box_bounds; Teuchos::Array<BoundingBox> boxes = boundingBoxes(); Teuchos::Array<BoundingBox>::const_iterator box_iterator; DTK_CHECK( !boxes.empty() ); for ( box_iterator = boxes.begin(); box_iterator != boxes.end(); ++box_iterator ) { box_bounds = box_iterator->getBounds(); if ( box_bounds[0] < global_x_min ) { global_x_min = box_bounds[0]; } if ( box_bounds[1] < global_y_min ) { global_y_min = box_bounds[1]; } if ( box_bounds[2] < global_z_min ) { global_z_min = box_bounds[2]; } if ( box_bounds[3] > global_x_max ) { global_x_max = box_bounds[3]; } if ( box_bounds[4] > global_y_max ) { global_y_max = box_bounds[4]; } if ( box_bounds[5] > global_z_max ) { global_z_max = box_bounds[5]; } } return BoundingBox( global_x_min, global_y_min, global_z_min, global_x_max, global_y_max, global_z_max ); }
//---------------------------------------------------------------------------// // Given an entity, get the ids of its support locations void LibmeshNodalShapeFunction::entitySupportIds( const DataTransferKit::Entity& entity, Teuchos::Array<DataTransferKit::SupportId>& support_ids ) const { // Node case. if ( 0 == entity.topologicalDimension() ) { DTK_CHECK( extractGeom<libMesh::Node>(entity)->valid_id() ); support_ids.assign( 1, extractGeom<libMesh::Node>(entity)->id() ); } // Element case. else { Teuchos::Ptr<libMesh::Elem> elem = extractGeom<libMesh::Elem>(entity); int num_nodes = elem->n_nodes(); support_ids.resize( num_nodes ); for ( int n = 0; n < num_nodes; ++n ) { DTK_CHECK( elem->get_node(n)->valid_id() ); support_ids[n] = elem->get_node(n)->id(); } } }
//---------------------------------------------------------------------------// // Given a local support id, dimension, and field value, write data into the // application field. void LibmeshVariableField::writeFieldData( const SupportId support_id, const int dimension, const double data ) { DTK_REQUIRE( 0 == dimension ); const libMesh::Node& node = d_libmesh_mesh->node( support_id ); DTK_CHECK( 1 == node.n_comp(d_system_id,d_variable_id) ); if ( node.processor_id() == d_libmesh_system->processor_id() ) { libMesh::dof_id_type dof_id = node.dof_number(d_system_id,d_variable_id,0); d_libmesh_system->solution->set( dof_id, data ); } }
NearestNeighborOperator<DeviceType>::NearestNeighborOperator( MPI_Comm comm, Kokkos::View<Coordinate const **, DeviceType> source_points, Kokkos::View<Coordinate const **, DeviceType> target_points ) : _comm( comm ) , _indices( "indices" ) , _ranks( "ranks" ) , _size( source_points.extent_int( 0 ) ) { // NOTE: instead of checking the pre-condition that there is at least one // source point passed to one of the rank, we let the tree handle the // communication and just check that the tree is not empty. // Build distributed search tree over the source points. DistributedSearchTree<DeviceType> search_tree( _comm, source_points ); // Tree must have at least one leaf, otherwise it makes little sense to // perform the search for nearest neighbors. DTK_CHECK( !search_tree.empty() ); // Query nearest neighbor for all target points. auto nearest_queries = Details::NearestNeighborOperatorImpl< DeviceType>::makeNearestNeighborQueries( target_points ); // Perform the actual search. Kokkos::View<int *, DeviceType> indices( "indices" ); Kokkos::View<int *, DeviceType> offset( "offset" ); Kokkos::View<int *, DeviceType> ranks( "ranks" ); search_tree.query( nearest_queries, indices, offset, ranks ); // Check post-condition that we did find a nearest neighbor to all target // points. DTK_ENSURE( lastElement( offset ) == target_points.extent_int( 0 ) ); // Save results. // NOTE: we don't bother keeping `offset` around since it is just `[0, 1, 2, // ..., n_target_poins]` _indices = indices; _ranks = ranks; }
//---------------------------------------------------------------------------// // Constructor. LibmeshVariableField::LibmeshVariableField( const Teuchos::RCP<libMesh::MeshBase>& libmesh_mesh, const Teuchos::RCP<libMesh::System>& libmesh_system, const std::string& variable_name ) : d_libmesh_mesh( libmesh_mesh ) , d_libmesh_system( libmesh_system ) { // Get ids. d_system_id = d_libmesh_system->number(); d_variable_id = d_libmesh_system->variable_number( variable_name ); // Get the local support ids. libMesh::MeshBase::const_node_iterator nodes_end = d_libmesh_mesh->local_nodes_end(); for ( libMesh::MeshBase::const_node_iterator node_it = d_libmesh_mesh->local_nodes_begin(); node_it != nodes_end; ++node_it ) { DTK_CHECK( (*node_it)->valid_id() ); d_support_ids.push_back( (*node_it)->id() ); } }
void SharedDomainMap<Mesh,CoordinateField>::setup( const RCP_MeshManager& source_mesh_manager, const RCP_CoordFieldManager& target_coord_manager, double tolerance ) { // Create existence values for the managers. bool source_exists = true; if ( source_mesh_manager.is_null() ) source_exists = false; bool target_exists = true; if ( target_coord_manager.is_null() ) target_exists = false; // Create local to global process indexers for the managers. RCP_Comm source_comm; if ( source_exists ) { source_comm = source_mesh_manager->comm(); } RCP_Comm target_comm; if ( target_exists ) { target_comm = target_coord_manager->comm(); } d_source_indexer = CommIndexer( d_comm, source_comm ); d_target_indexer = CommIndexer( d_comm, target_comm ); // Check the source and target dimensions for consistency. if ( source_exists ) { DTK_REQUIRE( source_mesh_manager->dim() == d_dimension ); } if ( target_exists ) { DTK_REQUIRE( CFT::dim( *target_coord_manager->field() ) == d_dimension ); } // Build the domain space and map from the source information. // ----------------------------------------------------------- // Create an entity set from the local source mesh. Teuchos::RCP<DataTransferKit::ClassicMesh<Mesh> > classic_mesh = Teuchos::rcp( new DataTransferKit::ClassicMesh<Mesh>(source_mesh_manager) ); ClassicMeshEntitySet<Mesh> source_entity_set( classic_mesh ); // Create a local map. ClassicMeshElementLocalMap<Mesh> source_local_map(classic_mesh); // Build the target space and map from the target information. // ----------------------------------------------------------- // Compute a unique global ordinal for each point in the coordinate field. Teuchos::Array<GlobalOrdinal> target_ordinals; computePointOrdinals( target_coord_manager, target_ordinals ); // Create an entity set from the local target points. BasicEntitySet target_entity_set( d_comm, d_dimension ); if ( target_exists ) { Teuchos::ArrayRCP<const typename CFT::value_type> coords_view = FieldTools<CoordinateField>::view( *target_coord_manager->field() ); Teuchos::Array<double> target_coords( d_dimension ); int local_num_targets = target_ordinals.size(); for ( int i = 0; i < local_num_targets; ++i ) { for ( int d = 0; d < d_dimension; ++d ) { target_coords[d] = coords_view[d*local_num_targets + i]; } target_entity_set.addEntity( DataTransferKit::Point( target_ordinals[i], d_comm->getRank(), target_coords ) ); } } // Create a local map. DataTransferKit::BasicGeometryLocalMap target_local_map; // Find the location of the target points in the source mesh. // -------------------------------------------------------------- // Create parameters for the mapping. Teuchos::ParameterList search_list; search_list.set<bool>("Track Missed Range Entities",d_store_missed_points); search_list.set<double>("Point Inclusion Tolerance", 1.0e-9 ); // Do the parallel search. EntityIterator source_iterator = source_entity_set.entityIterator( d_dimension ); EntityIterator target_iterator = target_entity_set.entityIterator( 0 ); ParallelSearch parallel_search( d_comm, d_dimension, source_iterator, Teuchos::rcpFromRef(source_local_map), search_list ); parallel_search.search( target_iterator, Teuchos::rcpFromRef(target_local_map), search_list ); // Build the mapping. // ----------------------- // Get the source-target parings. EntityIterator source_begin = source_iterator.begin(); EntityIterator source_end = source_iterator.end(); Teuchos::Array<EntityId> found_targets; Teuchos::Array<std::pair<EntityId,EntityId> > src_tgt_pairs; for ( auto src_geom = source_begin; src_geom != source_end; ++src_geom ) { // Get the target points found in this source geometry. parallel_search.getRangeEntitiesFromDomain( src_geom->id(), found_targets ); // If we found any points, add them to the mapping. for ( auto found_tgt : found_targets ) { src_tgt_pairs.push_back( std::make_pair(src_geom->id(),found_tgt) ); } } // Filter the source-target pairings so we only find a target point in one // geometry on this process. This handles the local uniqueness // problem. The tpetra import will handle the global uniqueness problem. auto sort_func = [] (std::pair<EntityId,EntityId> a, std::pair<EntityId,EntityId> b ) { return a.second < b.second; }; std::sort( src_tgt_pairs.begin(), src_tgt_pairs.end(), sort_func ); auto unique_func = [] (std::pair<EntityId,EntityId> a, std::pair<EntityId,EntityId> b ) { return a.second == b.second; }; auto unique_it = std::unique( src_tgt_pairs.begin(), src_tgt_pairs.end(), unique_func ); // Extract the mapping data. int num_tgt = std::distance( src_tgt_pairs.begin(), unique_it ); Teuchos::Array<GlobalOrdinal> source_ordinals( num_tgt ); d_source_geometry.resize( num_tgt ); d_target_coords.resize( num_tgt * d_dimension ); Teuchos::ArrayView<const double> tgt_coords; for ( int i = 0; i < num_tgt; ++i ) { // Get the source geom id. d_source_geometry[i] = src_tgt_pairs[i].first; // Get the target point id. source_ordinals[i] = src_tgt_pairs[i].second; // Get the coordinates of the target point. parallel_search.rangeParametricCoordinatesInDomain( src_tgt_pairs[i].first, src_tgt_pairs[i].second, tgt_coords ); for ( int d = 0; d < d_dimension; ++d ) { d_target_coords[ d*num_tgt + i ] = tgt_coords[d]; } } // Create the data map in the source decomposition. d_source_map = Tpetra::createNonContigMap<int,GlobalOrdinal>( source_ordinals(), d_comm ); // Create the data map in the target decomposition. d_target_map = Tpetra::createNonContigMap<int,GlobalOrdinal>( target_ordinals(), d_comm ); // Build the source-to-target importer. d_source_to_target_importer = Teuchos::rcp( new Tpetra::Import<int,GlobalOrdinal>( d_source_map, d_target_map ) ); // Extract the missed points. if ( d_store_missed_points ) { std::unordered_map<GlobalOrdinal,int> target_g2l; int local_num_targets = target_ordinals.size(); for ( int t = 0; t < local_num_targets; ++t ) { target_g2l.emplace( target_ordinals[t], t ); } Teuchos::ArrayView<const EntityId> missed = parallel_search.getMissedRangeEntityIds(); int num_missed = missed.size(); d_missed_points.resize( num_missed ); for ( int i = 0; i < num_missed; ++i ) { DTK_CHECK( target_g2l.count(missed[i]) ); d_missed_points[i] = target_g2l.find( missed[i] )->second; } } }
Teuchos::Array<double> CloudDomain<1>::center() const { DTK_CHECK( d_bounds[0] <= d_bounds[1] ); return Teuchos::Array<double>( 1, (d_bounds[1]+d_bounds[0]) / 2.0 ); }
void MovingLeastSquareReconstructionOperator<Basis,DIM>::setupImpl( const Teuchos::RCP<FunctionSpace>& domain_space, const Teuchos::RCP<FunctionSpace>& range_space ) { DTK_REQUIRE( Teuchos::nonnull(domain_space) ); DTK_REQUIRE( Teuchos::nonnull(range_space) ); // Extract the Support maps. const Teuchos::RCP<const typename Base::TpetraMap> domain_map = this->getDomainMap(); const Teuchos::RCP<const typename Base::TpetraMap> range_map = this->getRangeMap(); // Get the parallel communicator. Teuchos::RCP<const Teuchos::Comm<int> > comm = domain_map->getComm(); // Determine if we have range and domain data on this process. bool nonnull_domain = Teuchos::nonnull( domain_space->entitySet() ); bool nonnull_range = Teuchos::nonnull( range_space->entitySet() ); // We will only operate on entities that are locally-owned. LocalEntityPredicate local_predicate( comm->getRank() ); // Extract the source centers from the nodes and their ids. EntityIterator domain_iterator; if ( nonnull_domain ) { PredicateFunction domain_predicate = PredicateComposition::And( domain_space->selectFunction(), local_predicate.getFunction() ); domain_iterator = domain_space->entitySet()->entityIterator( d_domain_entity_dim, domain_predicate ); } int local_num_src = domain_iterator.size(); Teuchos::ArrayRCP<double> source_centers( DIM*local_num_src); Teuchos::ArrayRCP<GO> source_support_ids( local_num_src ); Teuchos::Array<SupportId> source_node_supports; EntityIterator domain_begin = domain_iterator.begin(); EntityIterator domain_end = domain_iterator.end(); int entity_counter = 0; for ( EntityIterator domain_entity = domain_begin; domain_entity != domain_end; ++domain_entity, ++entity_counter ) { domain_space->shapeFunction()->entitySupportIds( *domain_entity, source_node_supports ); DTK_CHECK( 1 == source_node_supports.size() ); source_support_ids[entity_counter] = source_node_supports[0]; domain_space->localMap()->centroid( *domain_entity, source_centers(DIM*entity_counter,DIM) ); } // Extract the target centers and their ids. EntityIterator range_iterator; if ( nonnull_range ) { PredicateFunction range_predicate = PredicateComposition::And( range_space->selectFunction(), local_predicate.getFunction() ); range_iterator = range_space->entitySet()->entityIterator( d_range_entity_dim, range_predicate ); } int local_num_tgt = range_iterator.size(); Teuchos::ArrayRCP<double> target_centers( DIM*local_num_tgt ); Teuchos::ArrayRCP<GO> target_support_ids( local_num_tgt ); Teuchos::Array<SupportId> target_node_supports; EntityIterator range_begin = range_iterator.begin(); EntityIterator range_end = range_iterator.end(); entity_counter = 0; for ( EntityIterator range_entity = range_begin; range_entity != range_end; ++range_entity, ++entity_counter ) { range_space->shapeFunction()->entitySupportIds( *range_entity, target_node_supports ); DTK_CHECK( 1 == target_node_supports.size() ); target_support_ids[entity_counter] = target_node_supports[0]; range_space->localMap()->centroid( *range_entity, target_centers(DIM*entity_counter,DIM) ); } // Build the basis. Teuchos::RCP<Basis> basis = BP::create( d_radius ); // Gather the source centers that are within a d_radius of the target // centers on this proc. Teuchos::Array<double> dist_sources; CenterDistributor<DIM> distributor( comm, source_centers(), target_centers(), d_radius, dist_sources ); // Gather the global ids of the source centers that are within a d_radius of // the target centers on this proc. Teuchos::Array<GO> dist_source_support_ids( distributor.getNumImports() ); Teuchos::ArrayView<const GO> source_support_ids_view = source_support_ids(); distributor.distribute( source_support_ids_view, dist_source_support_ids() ); // Build the source/target pairings. SplineInterpolationPairing<DIM> pairings( dist_sources, target_centers(), d_radius ); // Build the interpolation matrix. Teuchos::ArrayRCP<SupportId> children_per_parent = pairings.childrenPerParent(); SupportId max_entries_per_row = *std::max_element( children_per_parent.begin(), children_per_parent.end() ); d_coupling_matrix = Teuchos::rcp( new Tpetra::CrsMatrix<Scalar,LO,GO>( range_map, max_entries_per_row) ); Teuchos::ArrayView<const double> target_view; Teuchos::Array<GO> indices( max_entries_per_row ); Teuchos::ArrayView<const double> values; Teuchos::ArrayView<const unsigned> pair_gids; int nn = 0; for ( int i = 0; i < local_num_tgt; ++i ) { // If there is no support for this target center then do not build a // local basis. if ( 0 < pairings.childCenterIds(i).size() ) { // Get a view of this target center. target_view = target_centers(i*DIM,DIM); // Build the local interpolation problem. LocalMLSProblem<Basis,DIM> local_problem( target_view, pairings.childCenterIds(i), dist_sources, *basis ); // Get MLS shape function values for this target point. values = local_problem.shapeFunction(); nn = values.size(); // Populate the interpolation matrix row. pair_gids = pairings.childCenterIds(i); for ( int j = 0; j < nn; ++j ) { indices[j] = dist_source_support_ids[ pair_gids[j] ]; } d_coupling_matrix->insertGlobalValues( target_support_ids[i], indices(0,nn), values ); } } d_coupling_matrix->fillComplete( domain_map, range_map ); DTK_ENSURE( d_coupling_matrix->isFillComplete() ); }
Intrepid::FieldContainer<double> STKMeshHelpers::extractEntityNodeCoordinates( const Teuchos::Array<stk::mesh::Entity>& stk_entities, const stk::mesh::BulkData& bulk_data, const int space_dim ) { // Cast the field. const stk::mesh::FieldBase* coord_field_base= bulk_data.mesh_meta_data().coordinate_field(); const stk::mesh::Field<double,FieldType>* coord_field = dynamic_cast<const stk::mesh::Field<double,FieldType>* >( coord_field_base); // Allocate the coordinate array. int num_cells = stk_entities.size(); int num_nodes = 0; stk::mesh::EntityRank stk_rank = stk::topology::INVALID_RANK; if ( num_cells > 0 ) { stk_rank = bulk_data.entity_rank(stk_entities[0]); if ( stk::topology::NODE_RANK == stk_rank ) { num_nodes = 1; } else { const stk::mesh::Entity* begin = bulk_data.begin_nodes( stk_entities[0] ); const stk::mesh::Entity* end = bulk_data.end_nodes( stk_entities[0] ); num_nodes = std::distance( begin, end ); } } Intrepid::FieldContainer<double> coords( num_cells, num_nodes, space_dim ); // Extract the coordinates. double* node_coords = 0; for ( int c = 0; c < num_cells; ++c ) { if ( stk::topology::NODE_RANK == stk_rank ) { node_coords = stk::mesh::field_data( *coord_field, stk_entities[c] ); for ( int d = 0; d < space_dim; ++d ) { coords(c,0,d) = node_coords[d]; } } else { const stk::mesh::Entity* begin = bulk_data.begin_nodes( stk_entities[c] ); DTK_REMEMBER( const stk::mesh::Entity* end = bulk_data.end_nodes( stk_entities[c] ) ); DTK_CHECK( std::distance(begin,end) == num_nodes ); for ( int n = 0; n < num_nodes; ++n ) { node_coords = stk::mesh::field_data( *coord_field, begin[n] ); for ( int d = 0; d < space_dim; ++d ) { coords(c,n,d) = node_coords[d]; } } } } return coords; }
SplineCoefficientMatrix<Basis,DIM>::SplineCoefficientMatrix( const Teuchos::RCP<const Tpetra::Map<int,std::size_t> >& operator_map, const Teuchos::ArrayView<const double>& source_centers, const Teuchos::ArrayView<const std::size_t>& source_center_gids, const Teuchos::ArrayView<const double>& dist_source_centers, const Teuchos::ArrayView<const std::size_t>& dist_source_center_gids, const SplineInterpolationPairing<DIM>& source_pairings, const Basis& basis ) { DTK_CHECK( 0 == source_centers.size() % DIM ); DTK_CHECK( source_centers.size() / DIM == source_center_gids.size() ); DTK_CHECK( 0 == dist_source_centers.size() % DIM ); DTK_CHECK( dist_source_centers.size() / DIM == dist_source_center_gids.size() ); // Get the number of source centers. unsigned num_source_centers = source_center_gids.size(); // Create the P matrix. int offset = DIM + 1; Teuchos::RCP<Tpetra::MultiVector<double,int,std::size_t> > P_vec = Tpetra::createMultiVector<double,int,std::size_t>( operator_map, offset ); int di = 0; for ( unsigned i = 0; i < num_source_centers; ++i ) { P_vec->replaceGlobalValue( source_center_gids[i], 0, 1.0 ); di = DIM*i; for ( int d = 0; d < DIM; ++d ) { P_vec->replaceGlobalValue( source_center_gids[i], d+1, source_centers[di+d] ); } } d_P =Teuchos::rcp( new PolynomialMatrix<std::size_t>(P_vec,operator_map,operator_map) ); // Create the M matrix. Teuchos::ArrayRCP<std::size_t> children_per_parent = source_pairings.childrenPerParent(); std::size_t max_entries_per_row = *std::max_element( children_per_parent.begin(), children_per_parent.end() ); d_M = Teuchos::rcp( new Tpetra::CrsMatrix<double,int,std::size_t>( operator_map, max_entries_per_row) ); Teuchos::Array<std::size_t> M_indices( max_entries_per_row ); Teuchos::Array<double> values( max_entries_per_row ); int dj = 0; Teuchos::ArrayView<const unsigned> source_neighbors; double dist = 0.0; int nsn = 0; for ( unsigned i = 0; i < num_source_centers; ++i ) { // Get the source points neighboring this source point. di = DIM*i; source_neighbors = source_pairings.childCenterIds( i ); nsn = source_neighbors.size(); // Add the local basis contributions. for ( int j = 0; j < nsn; ++j ) { dj = DIM*source_neighbors[j]; M_indices[j] = dist_source_center_gids[ source_neighbors[j] ]; dist = EuclideanDistance<DIM>::distance( &source_centers[di], &dist_source_centers[dj] ); values[j] = BP::evaluateValue( basis, dist ); } d_M->insertGlobalValues( source_center_gids[i], M_indices(0,nsn), values(0,nsn) ); } d_M->fillComplete(); DTK_ENSURE( d_M->isFillComplete() ); }