163  const Ordinal first_ele_offset_in = 0;
 
  167  using Teuchos::ptr_dynamic_cast;
 
  168  using Teuchos::tuple;
 
  170  const int num_vecs = vecs.size();
 
  171  const int num_targ_vecs = targ_vecs.size();
 
  176    global_offset_in < 0, std::invalid_argument,
 
  177    "DefaultClusteredSpmdProductVector::applyOp(...): Error, " 
  178    "global_offset_in = " << global_offset_in << 
" is not acceptable" );
 
  180  for (
int k = 0; k < num_vecs; ++k) {
 
  181    test_failed = !this->space()->isCompatible(*vecs[k]->space());
 
  184      "DefaultClusteredSpmdProductVector::applyOp(...): Error vecs["<<k<<
"]->space() " 
  185      <<
"of type \'"<<typeName(*vecs[k]->space())<<
"\' is not compatible with this " 
  186      <<
"\'VectorSpaceBlocked\' vector space!" 
  189  for (
int k = 0; k < num_targ_vecs; ++k) {
 
  190    test_failed = !this->space()->isCompatible(*targ_vecs[k]->space());
 
  193      ,
"DefaultClusteredSpmdProductVector::applyOp(...): Error targ_vecs["<<k<<
"]->space() " 
  194      <<
"of type \'"<<typeName(*vecs[k]->space())<<
"\' is not compatible with this " 
  195      <<
"\'VectorSpaceBlocked\' vector space!" 
  205  for ( 
int k = 0; k < num_vecs; ++k ) {
 
  209    cl_vecs[k] = ptr_dynamic_cast<const DefaultClusteredSpmdProductVector<Scalar> >(vecs[k],
true);
 
  212  for ( 
int k = 0; k < num_targ_vecs; ++k ) {
 
  216    cl_targ_vecs[k] = ptr_dynamic_cast<DefaultClusteredSpmdProductVector<Scalar> >(targ_vecs[k],
true);
 
  224    intraClusterComm = productSpace_->intraClusterComm(),
 
  225    interClusterComm = productSpace_->interClusterComm();
 
  227    clusterSubDim = productSpace_->clusterSubDim(),
 
  228    clusterOffset = productSpace_->clusterOffset(),
 
  229    globalDim = productSpace_->dim();
 
  230  Ordinal  overlap_first_cluster_ele_off  = 0;
 
  231  Ordinal  overlap_cluster_sub_dim        = 0;
 
  232  Ordinal  overlap_global_off             = 0;
 
  234    RTOp_parallel_calc_overlap(
 
  235      globalDim,clusterSubDim,clusterOffset,first_ele_offset_in,sub_dim_in
 
  237      ,&overlap_first_cluster_ele_off,&overlap_cluster_sub_dim,&overlap_global_off
 
  246  if (!is_null(reduct_obj))
 
  250  const int numBlocks = vecs_.size();
 
  251  if (overlap_first_cluster_ele_off >=0) {
 
  259    Ordinal overall_global_offset = overlap_global_off;
 
  260    for( 
int j = 0; j < numBlocks; ++j ) {
 
  264        &v_space = *v.
space();
 
  266      for( 
int k = 0; k < num_vecs ; ++k )
 
  267        v_vecs[k] = cl_vecs[k]->vecs_[j].ptr();
 
  268      for( 
int k = 0; k < num_targ_vecs ; ++k )
 
  269        v_targ_vecs[k] = cl_targ_vecs[k]->vecs_[j].ptr();
 
  271        numBlocks > 1, std::logic_error
 
  272        ,
"Error, Have not implemented general support for numBlocks > 1!" 
  274      Ordinal v_global_offset = overall_global_offset;
 
  276      Thyra::applyOp<Scalar>(
 
  277        op, v_vecs(), v_targ_vecs(), i_reduct_obj.
ptr(),
 
  280      overall_global_offset += v_space.
dim();
 
  290  if (!is_null(reduct_obj)) {
 
  296    if (interClusterComm.get()) {
 
  297      RTOpPack::SPMD_all_reduce(
 
  301        tuple<const RTOpPack::ReductTarget*>(&*i_reduct_obj).getRawPtr(),
 
  302        tuple<RTOpPack::ReductTarget*>(&*icl_reduct_obj).getRawPtr()
 
  310    RTOpPack::SPMD_all_reduce(
 
  314      tuple<const RTOpPack::ReductTarget*>(&*icl_reduct_obj).getRawPtr(),
 
  315      tuple<RTOpPack::ReductTarget*>(&*reduct_obj).getRawPtr()