//---------------------------------------------------------------------------//
// 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() );
}