void FieldManager<Field>::validate()
{
    // Check that the field dimension is the same on every node.
    Teuchos::Array<int> local_dims( d_comm->getSize(), 0 );
    Teuchos::Array<int> local_dims_copy( d_comm->getSize(), 0 );
    local_dims[ d_comm->getRank() ] = FT::dim( *d_field );
    Teuchos::reduceAll<int,int>( *d_comm, Teuchos::REDUCE_SUM,
				 local_dims.size(),
				 &local_dims[0], &local_dims_copy[0] ); 
    Teuchos::Array<int>::iterator unique_bound;
    std::sort( local_dims_copy.begin(), local_dims_copy.end() );
    unique_bound = std::unique( local_dims_copy.begin(), local_dims_copy.end() );
    int unique_dim = std::distance( local_dims_copy.begin(), unique_bound );
    testPrecondition( 1 == unique_dim );
    local_dims_copy.clear();

    // Check that the data dimension is the same as the field dimension.
    typename FT::size_type num_data = std::distance( FT::begin( *d_field ), 
						     FT::end( *d_field ) );
    testPrecondition( num_data == FT::size( *d_field ) );
    if ( !FT::empty( *d_field ) )
    {
	testPrecondition( num_data / FieldTools<Field>::dimSize( *d_field ) 
			  == Teuchos::as<typename FT::size_type>(
			      FT::dim(*d_field)) );
    }
}
void GeometryManager<Geometry,GlobalOrdinal>::validate()
{
    // Dimensions greater than 3 are not valid.
    DTK_REQUIRE( 0 <= d_dim && d_dim <= 3 );

    // Check that all local geometries have the same dimension.
    typename Teuchos::ArrayRCP<Geometry>::const_iterator geom_iterator;
    for ( geom_iterator = d_geometry.begin();
	  geom_iterator != d_geometry.end();
	  ++geom_iterator )
    {
	DTK_REQUIRE( GT::dim( *geom_iterator ) == d_dim );
    }

    // Check that the geometry dimension is the same on every node.
    Teuchos::Array<int> local_dims( d_comm->getSize(), 0 );
    Teuchos::Array<int> local_dims_copy( d_comm->getSize(), 0 );
    local_dims[ d_comm->getRank() ] = d_dim;
    Teuchos::reduceAll<int,int>( *d_comm, Teuchos::REDUCE_SUM,
				 local_dims.size(),
				 &local_dims[0], &local_dims_copy[0] ); 
    Teuchos::Array<int>::iterator unique_bound;
    std::sort( local_dims_copy.begin(), local_dims_copy.end() );
    unique_bound = 
	std::unique( local_dims_copy.begin(), local_dims_copy.end() );
    int unique_dim = std::distance( local_dims_copy.begin(), unique_bound );
    DTK_REQUIRE( 1 == unique_dim );
    local_dims_copy.clear();
}
void MeshManager<Mesh>::validate()
{
    // Check that the mesh is of a valid dimension.
    DTK_REQUIRE( 0 <= d_dim && d_dim <= 3 );

    // Check that the mesh dimension is the same on every node.
    Teuchos::Array<int> local_dims( d_comm->getSize(), 0 );
    Teuchos::Array<int> local_dims_copy( d_comm->getSize(), 0 );
    local_dims[ d_comm->getRank() ] = d_dim;
    Teuchos::reduceAll<int,int>( *d_comm, Teuchos::REDUCE_SUM,
				 local_dims.size(),
				 &local_dims[0], &local_dims_copy[0] ); 
    Teuchos::Array<int>::iterator unique_bound;
    std::sort( local_dims_copy.begin(), local_dims_copy.end() );
    unique_bound = std::unique( local_dims_copy.begin(), local_dims_copy.end() );
    int unique_dim = std::distance( local_dims_copy.begin(), unique_bound );
    DTK_REQUIRE( 1 == unique_dim );
    local_dims_copy.clear();

    // Check that the same number of blocks have been defined on every node.
    Teuchos::Array<int> local_blocks( d_comm->getSize(), 0 );
    Teuchos::Array<int> local_blocks_copy( d_comm->getSize(), 0 );
    local_blocks[ d_comm->getRank() ] = getNumBlocks();
    Teuchos::reduceAll<int,int>( *d_comm, Teuchos::REDUCE_SUM,
				 local_blocks.size(),
				 &local_blocks[0], &local_blocks_copy[0] ); 
    std::sort( local_blocks_copy.begin(), local_blocks_copy.end() );
    unique_bound = std::unique( local_blocks_copy.begin(), local_blocks_copy.end() );
    int unique_blocks = std::distance( local_blocks_copy.begin(), unique_bound );
    DTK_REQUIRE( 1 == unique_blocks );
    local_blocks_copy.clear();

    // Check the mesh blocks.
    BlockIterator block_iterator;
    for ( block_iterator = d_mesh_blocks.begin();
	  block_iterator != d_mesh_blocks.end();
	  ++block_iterator )
    {
	// Check that the block vertices are the same dimension as the mesh.
	DTK_REQUIRE( d_dim == MT::vertexDim( *(*block_iterator) ) );

	// Check that the coordinate dimension is the same as the mesh
	// dimension.
	GlobalOrdinal num_vertices = 
	    MeshTools<Mesh>::numVertices( *(*block_iterator) );
	GlobalOrdinal num_coords = std::distance( 
	    MT::coordsBegin( *(*block_iterator) ), 
	    MT::coordsEnd( *(*block_iterator) ) );
	if ( num_vertices > 0 )
	{
	    DTK_REQUIRE( num_coords / num_vertices 
			      == Teuchos::as<GlobalOrdinal>(d_dim) );
	}
	
	// Check that the element topology is valid for the given dimension.
	if ( d_dim == 0 )
	{
	    DTK_REQUIRE( MT::elementTopology( *(*block_iterator) ) 
			      == DTK_VERTEX );
	}
	else if ( d_dim == 1 )
	{
	    DTK_REQUIRE( MT::elementTopology( *(*block_iterator) ) == 
			      DTK_LINE_SEGMENT );
	}
	else if ( d_dim == 2 )
	{
	    DTK_REQUIRE( MT::elementTopology( *(*block_iterator) ) == 
			      DTK_TRIANGLE ||
			      MT::elementTopology( *(*block_iterator) ) == 
			      DTK_QUADRILATERAL );
	}
	else if ( d_dim == 3 )
	{
	    DTK_REQUIRE( MT::elementTopology( *(*block_iterator) ) == 
			      DTK_TETRAHEDRON ||
			      MT::elementTopology( *(*block_iterator) ) == 
			      DTK_HEXAHEDRON ||
			      MT::elementTopology( *(*block_iterator) ) == 
			      DTK_PYRAMID ||
			      MT::elementTopology( *(*block_iterator) ) == 
			      DTK_WEDGE );
	}

	// Check that this block has the same topology on all nodes.
	Teuchos::Array<int> local_topo( d_comm->getSize(), 0 );
	Teuchos::Array<int> local_topo_copy( d_comm->getSize(), 0 );
	local_topo[ d_comm->getRank() ] = 
	    Teuchos::as<int>(MT::elementTopology( *(*block_iterator) ));
	Teuchos::reduceAll<int,int>( *d_comm, Teuchos::REDUCE_SUM,
				     local_topo.size(),
				     &local_topo[0], &local_topo_copy[0] ); 
	std::sort( local_topo_copy.begin(), local_topo_copy.end() );
	unique_bound = std::unique( local_topo_copy.begin(), local_topo_copy.end() );
	int unique_topo = std::distance( local_topo_copy.begin(), unique_bound );
	DTK_REQUIRE( 1 == unique_topo );
	local_topo_copy.clear();

	// Check that the element handles are of a value less than the numeric
	// limit of the ordinal type. This is an invalid element handle.
	typename MT::const_element_iterator element_iterator;
	for ( element_iterator = MT::elementsBegin( *(*block_iterator) );
	      element_iterator != MT::elementsEnd( *(*block_iterator) );
	      ++element_iterator )
	{
	    DTK_REQUIRE( *element_iterator < 
			      std::numeric_limits<GlobalOrdinal>::max() );
	}
	
	// Check that the connectivity size is the same as the number of
	// vertices per element.
	GlobalOrdinal num_elements =
	    MeshTools<Mesh>::numElements( *(*block_iterator) );
	GlobalOrdinal num_conn = std::distance( 
	    MT::connectivityBegin( *(*block_iterator) ),
	    MT::connectivityEnd( *(*block_iterator) ) );
	if ( num_elements > Teuchos::as<GlobalOrdinal>(0) )
	{
	    DTK_REQUIRE( num_conn / num_elements ==
			      Teuchos::as<GlobalOrdinal>(
				  MT::verticesPerElement(*(*block_iterator))) );
	}

	// Check that the size of the permutation vector is the same as the
	// number of vertices per element.
	int num_permutation = std::distance(
	    MT::permutationBegin( *(*block_iterator) ),
	    MT::permutationEnd( *(*block_iterator) ) );
	DTK_REQUIRE( MT::verticesPerElement( *(*block_iterator) ) ==
			  num_permutation );

	// Check that the permutation vector contains unique values.
	Teuchos::Array<int> permutation( num_permutation );
	std::copy( MT::permutationBegin( *(*block_iterator) ),
		   MT::permutationEnd( *(*block_iterator) ), 
		   permutation.begin() );
	Teuchos::Array<int>::iterator permutation_bound;
	std::sort( permutation.begin(), permutation.end() );
	permutation_bound = std::unique( permutation.begin(),
					 permutation.end() );
	int unique_permutation = std::distance( permutation.begin(),
						permutation_bound );
	DTK_REQUIRE( MT::verticesPerElement( *(*block_iterator) ) ==
			  unique_permutation );

	// Check that the permutation vector contains value less than its
	// size. This implies that we shouldn't get more vertices in the
	// connectivity list than are needed to build the linear element.
	typename MT::const_permutation_iterator permutation_it;
	for ( permutation_it = MT::permutationBegin( *(*block_iterator) );
	      permutation_it != MT::permutationEnd( *(*block_iterator) );
	      ++permutation_it )
	{
	    DTK_REQUIRE( *permutation_it < 
			      MT::verticesPerElement( *(*block_iterator) ) );
	}

	d_comm->barrier();
    }
}