//---------------------------------------------------------------------------// // Test the postcondition check for DBC. TEUCHOS_UNIT_TEST( DataTransferKitException, postcondition_test ) { try { DTK_ENSURE( 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 } }
//---------------------------------------------------------------------------// // 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) ); }
//---------------------------------------------------------------------------// //! Default constructor. STKMeshManager::STKMeshManager( const Teuchos::RCP<stk::mesh::BulkData>& bulk_data, const BasisType basis_type ) : d_bulk_data( bulk_data ) { createFunctionSpace( basis_type, FunctionSpace::selectAll ); DTK_ENSURE( Teuchos::nonnull(d_function_space) ); }
//---------------------------------------------------------------------------// //! Selector constructor. STKMeshManager::STKMeshManager( const Teuchos::RCP<stk::mesh::BulkData>& bulk_data, const stk::mesh::Selector& selector, const BasisType basis_type ) : d_bulk_data( bulk_data ) { STKSelectorPredicate pred( selector ); createFunctionSpace( basis_type, pred.getFunction() ); DTK_ENSURE( Teuchos::nonnull(d_function_space) ); }
//---------------------------------------------------------------------------// //! Part name constructor. STKMeshManager::STKMeshManager( const Teuchos::RCP<stk::mesh::BulkData>& bulk_data, const Teuchos::Array<std::string>& part_names, const BasisType basis_type ) : d_bulk_data( bulk_data ) { STKPartNamePredicate pred( part_names, d_bulk_data ); createFunctionSpace( basis_type, pred.getFunction() ); DTK_ENSURE( Teuchos::nonnull(d_function_space) ); }
/*! * \brief Constructor. */ CoarseLocalSearch::CoarseLocalSearch( const EntityIterator& entity_iterator, const Teuchos::RCP<EntityLocalMap>& local_map, const Teuchos::ParameterList& parameters ) { // Setup the centroid array. These will be interleaved. int space_dim = 0; int num_entity = entity_iterator.size(); if ( num_entity > 0 ) { space_dim = entity_iterator.begin()->physicalDimension(); } d_entity_centroids.resize( space_dim * num_entity ); // Add the centroids. EntityIterator entity_it; EntityIterator begin_it = entity_iterator.begin(); EntityIterator end_it = entity_iterator.end(); int entity_local_id = 0; for ( entity_it = begin_it; entity_it != end_it; ++entity_it ) { local_map->centroid( *entity_it, d_entity_centroids(space_dim*entity_local_id,space_dim) ); d_entity_map.emplace( entity_local_id, *entity_it ); ++entity_local_id; } // Build a static search tree. int leaf_size = 20; if ( parameters.isParameter("Coarse Local Search Leaf Size") ) { leaf_size = parameters.get<int>("Coarse Local Search Leaf Size"); } leaf_size = std::min( leaf_size, num_entity ); d_tree = SearchTreeFactory::createStaticTree( space_dim, d_entity_centroids(), leaf_size ); DTK_ENSURE( Teuchos::nonnull(d_tree) ); }
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; }
void MovingLeastSquareReconstructionOperator<Scalar,Basis,DIM>::setup( const Teuchos::RCP<const typename Base::TpetraMap>& domain_map, const Teuchos::RCP<FunctionSpace>& domain_space, const Teuchos::RCP<const typename Base::TpetraMap>& range_map, const Teuchos::RCP<FunctionSpace>& range_space, const Teuchos::RCP<Teuchos::ParameterList>& parameters ) { DTK_REQUIRE( Teuchos::nonnull(domain_map) ); DTK_REQUIRE( Teuchos::nonnull(domain_space) ); DTK_REQUIRE( Teuchos::nonnull(range_map) ); DTK_REQUIRE( Teuchos::nonnull(range_space) ); DTK_REQUIRE( Teuchos::nonnull(parameters) ); // 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() ); // Make sure we are applying the map to nodes. DTK_REQUIRE( domain_space->entitySelector()->entityType() == ENTITY_TYPE_NODE ); DTK_REQUIRE( range_space->entitySelector()->entityType() == ENTITY_TYPE_NODE ); // Extract the DOF maps. this->b_domain_map = domain_map; this->b_range_map = range_map; // Extract the source centers and their ids. EntityIterator domain_iterator; if ( nonnull_domain ) { domain_iterator = domain_space->entitySet()->entityIterator( domain_space->entitySelector()->entityType(), domain_space->entitySelector()->selectFunction() ); } int local_num_src = domain_iterator.size(); Teuchos::ArrayRCP<double> source_centers( DIM*local_num_src); Teuchos::ArrayRCP<GO> source_gids( local_num_src ); 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 ) { source_gids[entity_counter] = domain_entity->id(); 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 ) { range_iterator = range_space->entitySet()->entityIterator( range_space->entitySelector()->entityType(), range_space->entitySelector()->selectFunction() ); } int local_num_tgt = range_iterator.size(); Teuchos::ArrayRCP<double> target_centers( DIM*local_num_tgt ); Teuchos::ArrayRCP<GO> target_gids( local_num_tgt ); 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 ) { target_gids[entity_counter] = range_entity->id(); 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 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 radius of // the target centers on this proc. Teuchos::Array<GO> dist_source_gids( distributor.getNumImports() ); Teuchos::ArrayView<const GO> source_gids_view = source_gids(); distributor.distribute( source_gids_view, dist_source_gids() ); // Build the source/target pairings. SplineInterpolationPairing<DIM> pairings( dist_sources, target_centers(), d_radius ); // Build the interpolation matrix. Teuchos::ArrayRCP<std::size_t> children_per_parent = pairings.childrenPerParent(); std::size_t max_entries_per_row = *std::max_element( children_per_parent.begin(), children_per_parent.end() ); Teuchos::RCP<Tpetra::CrsMatrix<Scalar,int,GO> > H = Teuchos::rcp( new Tpetra::CrsMatrix<Scalar,int,GO>( this->b_range_map, max_entries_per_row) ); Teuchos::ArrayView<const Scalar> target_view; Teuchos::Array<GO> indices( max_entries_per_row ); Teuchos::ArrayView<const Scalar> 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_gids[ pair_gids[j] ]; } H->insertGlobalValues( target_gids[i], indices(0,nn), values ); } } H->fillComplete( this->b_domain_map, this->b_range_map ); DTK_ENSURE( H->isFillComplete() ); // Wrap the interpolation matrix in a Thyra wrapper. Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> > thyra_range_vector_space = Thyra::createVectorSpace<Scalar>( H->getRangeMap() ); Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> > thyra_domain_vector_space = Thyra::createVectorSpace<Scalar>( H->getDomainMap() ); Teuchos::RCP<Thyra::TpetraLinearOp<Scalar,LO,GO> > thyra_H = Teuchos::rcp( new Thyra::TpetraLinearOp<Scalar,LO,GO>() ); thyra_H->initialize( thyra_range_vector_space, thyra_domain_vector_space, H ); // Set the coupling matrix with the base class. this->b_coupling_matrix = thyra_H; DTK_ENSURE( Teuchos::nonnull(this->b_coupling_matrix) ); }
void NewtonSolver<NonlinearProblem>::solve( MDArray& u, NonlinearProblem& problem, const double tolerance, const int max_iters ) { DTK_REQUIRE( 2 == u.rank() ); // Allocate nonlinear residual, Jacobian, Newton update, and work arrays. int d0 = u.dimension(0); int d1 = u.dimension(1); MDArray F( d0, d1 ); MDArray J( d0, d1, d1 ); MDArray J_inv( d0, d1, d1 ); MDArray update( d0, d1 ); MDArray u_old = u; MDArray conv_check( d0 ); // Compute the initial state. NPT::updateState( problem, u ); // Computen the initial nonlinear residual and scale by -1 to get -F(u). NPT::evaluateResidual( problem, u, F ); Intrepid::RealSpaceTools<Scalar>::scale( F, -Teuchos::ScalarTraits<Scalar>::one() ); // Compute the initial Jacobian. NPT::evaluateJacobian( problem, u, J ); // Check for degeneracy of the Jacobian. If it is degenerate then the // problem is ill conditioned and return very large numbers in the state // vector that correspond to no solution. MDArray det( 1 ); Intrepid::RealSpaceTools<Scalar>::det( det, J ); if ( std::abs(det(0)) < tolerance ) { for ( int m = 0; m < d0; ++m ) { for ( int n = 0; n < d1; ++n ) { u(m,n) = std::numeric_limits<Scalar>::max(); } } return; } // Nonlinear solve. for ( int k = 0; k < max_iters; ++k ) { // Solve the linear model, delta_u = J^-1 * -F(u). Intrepid::RealSpaceTools<Scalar>::inverse( J_inv, J ); Intrepid::RealSpaceTools<Scalar>::matvec( update, J_inv, F ); // Update the solution, u += delta_u. Intrepid::RealSpaceTools<Scalar>::add( u, update ); // Check for convergence. Intrepid::RealSpaceTools<Scalar>::subtract( u_old, u ); Intrepid::RealSpaceTools<Scalar>::vectorNorm( conv_check, u_old, Intrepid::NORM_TWO ); if ( tolerance > conv_check(0) ) { break; } // Reset for the next iteration. u_old = u; // Update any state-dependent data from the last iteration using the // new solution vector. NPT::updateState( problem, u ); // Compute the nonlinear residual and scale by -1 to get -F(u). NPT::evaluateResidual( problem, u, F ); Intrepid::RealSpaceTools<Scalar>::scale( F, -Teuchos::ScalarTraits<Scalar>::one() ); // Compute the Jacobian. NPT::evaluateJacobian( problem, u, J ); } // Check for convergence. DTK_ENSURE( tolerance > conv_check(0) ); }
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() ); }
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() ); }