Thyra  Version of the Day
Thyra_DefaultProductMultiVector_def.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Roscoe A. Bartlett (bartlettra@ornl.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_DEF_HPP
43 #define THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_DEF_HPP
44 
45 #include "Thyra_DefaultProductMultiVector_decl.hpp"
46 #include "Thyra_DefaultProductVectorSpace.hpp"
47 #include "Thyra_DefaultProductVector.hpp"
48 #include "Thyra_AssertOp.hpp"
49 
50 
51 namespace Thyra {
52 
53 
54 // Constructors/initializers/accessors
55 
56 
57 template<class Scalar>
59  :numBlocks_(0)
60 {}
61 
62 
63 template<class Scalar>
65  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
66  const int numMembers
67  )
68 {
69 #ifdef TEUCHOS_DEBUG
70  TEUCHOS_TEST_FOR_EXCEPT( is_null(productSpace_in) );
71  TEUCHOS_TEST_FOR_EXCEPT( numMembers <= 0 );
72 #endif
73  Array<RCP<MultiVectorBase<Scalar> > > multiVecs;
74  const int numBlocks = productSpace_in->numBlocks();
75  for ( int k = 0; k < numBlocks; ++k )
76  multiVecs.push_back(createMembers(productSpace_in->getBlock(k),numMembers));
77  initialize(productSpace_in,multiVecs);
78 }
79 
80 
81 template<class Scalar>
83  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
84  const ArrayView<const RCP<MultiVectorBase<Scalar> > > &multiVecs
85  )
86 {
87  initializeImpl(productSpace_in,multiVecs);
88 }
89 
90 
91 template<class Scalar>
93  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
94  const ArrayView<const RCP<const MultiVectorBase<Scalar> > > &multiVecs
95  )
96 {
97  initializeImpl(productSpace_in,multiVecs);
98 }
99 
100 
101 template<class Scalar>
103 {
104  productSpace_ = Teuchos::null;
105  multiVecs_.resize(0);
106  numBlocks_ = 0;
107 }
108 
109 
110 // Overridden public functions from Teuchos::Describable
111 
112 
113 template<class Scalar>
115 {
116  std::ostringstream oss;
117  oss
118  << Teuchos::Describable::description()
119  << "{"
120  << "rangeDim="<<this->range()->dim()
121  << ",domainDim="<<this->domain()->dim()
122  << ",numBlocks = "<<numBlocks_
123  << "}";
124  return oss.str();
125 }
126 
127 
128 template<class Scalar>
130  FancyOStream &out_arg,
131  const Teuchos::EVerbosityLevel verbLevel
132  ) const
133 {
134  using Teuchos::OSTab;
135  using Teuchos::describe;
136  if (verbLevel == Teuchos::VERB_NONE)
137  return;
138  RCP<FancyOStream> out = rcp(&out_arg,false);
139  OSTab tab(out);
140  switch(verbLevel) {
141  case Teuchos::VERB_NONE:
142  break;
143  case Teuchos::VERB_DEFAULT: // fall through
144  case Teuchos::VERB_LOW: // fall through
145  *out << this->description() << std::endl;
146  break;
147  case Teuchos::VERB_MEDIUM: // fall through
148  case Teuchos::VERB_HIGH: // fall through
149  case Teuchos::VERB_EXTREME:
150  {
151  *out
152  << Teuchos::Describable::description() << "{"
153  << "rangeDim="<<this->range()->dim()
154  << ",domainDim="<<this->domain()->dim()
155  << "}\n";
156  OSTab tab2(out);
157  *out
158  << "numBlocks="<< numBlocks_ << std::endl
159  << "Constituent multi-vector objects V[0], V[1], ... V[numBlocks-1]:\n";
160  OSTab tab3(out);
161  for( int k = 0; k < numBlocks_; ++k ) {
162  *out << "V["<<k<<"] = "
163  << Teuchos::describe(*multiVecs_[k].getConstObj(),verbLevel);
164  }
165  break;
166  }
167  default:
168  TEUCHOS_TEST_FOR_EXCEPT(true); // Should never get here!
169  }
170 }
171 
172 
173 // Overridden public functions from ProductMultiVectorBase
174 
175 
176 template<class Scalar>
177 RCP<const ProductVectorSpaceBase<Scalar> >
179 {
180  return productSpace_;
181 }
182 
183 
184 template<class Scalar>
186 {
187  return multiVecs_[k].isConst();
188 }
189 
190 
191 template<class Scalar>
192 RCP<MultiVectorBase<Scalar> >
194 {
195  return multiVecs_[k].getNonconstObj();
196 }
197 
198 
199 template<class Scalar>
200 RCP<const MultiVectorBase<Scalar> >
202 {
203  return multiVecs_[k].getConstObj();
204 }
205 
206 
207 // Overridden public functions from MultiVectorBase
208 
209 
210 template<class Scalar>
211 RCP<MultiVectorBase<Scalar> >
213 {
214  assertInitialized();
215  Array<RCP<MultiVectorBase<Scalar> > > blocks;
216  for ( int k = 0; k < numBlocks_; ++k )
217  blocks.push_back(multiVecs_[k].getConstObj()->clone_mv());
218  return defaultProductMultiVector<Scalar>(productSpace_, blocks());
219 }
220 
221 
222 // Overriden public functions from LinearOpBase
223 
224 
225 template<class Scalar>
226 RCP< const VectorSpaceBase<Scalar> >
228 {
229  return productSpace_;
230 }
231 
232 
233 template<class Scalar>
234 RCP< const VectorSpaceBase<Scalar> >
236 {
237  if (is_null(productSpace_))
238  return Teuchos::null;
239  return multiVecs_[0].getConstObj()->domain();
240 }
241 
242 
243 // protected
244 
245 
246 // Overriden protected functions from MultiVectorBase
247 
248 
249 template<class Scalar>
251 {
252  for ( int k = 0; k < numBlocks_; ++k ) {
253  multiVecs_[k].getNonconstObj()->assign(alpha);
254  }
255 }
256 
257 
258 template<class Scalar>
259 RCP<const VectorBase<Scalar> >
261 {
262  validateColIndex(j);
263  Array<RCP<const VectorBase<Scalar> > > cols_;
264  for ( int k = 0; k < numBlocks_; ++k )
265  cols_.push_back(multiVecs_[k].getConstObj()->col(j));
266  return defaultProductVector<Scalar>(productSpace_, cols_());
267 }
268 
269 
270 template<class Scalar>
271 RCP<VectorBase<Scalar> >
273 {
274  validateColIndex(j);
275  Array<RCP<VectorBase<Scalar> > > cols_;
276  for ( int k = 0; k < numBlocks_; ++k )
277  cols_.push_back(multiVecs_[k].getNonconstObj()->col(j));
278  return defaultProductVector<Scalar>(productSpace_, cols_());
279 }
280 
281 
282 template<class Scalar>
283 RCP<const MultiVectorBase<Scalar> >
285 {
286  assertInitialized();
287  Array<RCP<const MultiVectorBase<Scalar> > > blocks;
288  for ( int k = 0; k < numBlocks_; ++k )
289  blocks.push_back(multiVecs_[k].getConstObj()->subView(colRng));
290  return defaultProductMultiVector<Scalar>(productSpace_, blocks());
291 }
292 
293 
294 template<class Scalar>
295 RCP<MultiVectorBase<Scalar> >
297 {
298  assertInitialized();
299  Array<RCP<MultiVectorBase<Scalar> > > blocks;
300  for ( int k = 0; k < numBlocks_; ++k )
301  blocks.push_back(multiVecs_[k].getNonconstObj()->subView(colRng));
302  return defaultProductMultiVector<Scalar>(productSpace_, blocks());
303 }
304 
305 
306 template<class Scalar>
307 RCP<const MultiVectorBase<Scalar> >
309  const ArrayView<const int> &cols
310  ) const
311 {
312  assertInitialized();
313  Array<RCP<const MultiVectorBase<Scalar> > > blocks;
314  for ( int k = 0; k < numBlocks_; ++k )
315  blocks.push_back(multiVecs_[k].getConstObj()->subView(cols));
316  return defaultProductMultiVector<Scalar>(productSpace_, blocks());
317 }
318 
319 
320 template<class Scalar>
321 RCP<MultiVectorBase<Scalar> >
323  const ArrayView<const int> &cols
324  )
325 {
326  assertInitialized();
327  Array<RCP<MultiVectorBase<Scalar> > > blocks;
328  for ( int k = 0; k < numBlocks_; ++k )
329  blocks.push_back(multiVecs_[k].getNonconstObj()->subView(cols));
330  return defaultProductMultiVector<Scalar>(productSpace_, blocks());
331 }
332 
333 
334 template<class Scalar>
336  const RTOpPack::RTOpT<Scalar> &primary_op,
337  const ArrayView<const Ptr<const MultiVectorBase<Scalar> > > &multi_vecs_in,
338  const ArrayView<const Ptr<MultiVectorBase<Scalar> > > &targ_multi_vecs_inout,
339  const ArrayView<const Ptr<RTOpPack::ReductTarget> > &reduct_objs,
340  const Ordinal primary_global_offset_in
341  ) const
342 {
343 
344  using Teuchos::ptr_dynamic_cast;
345  using Thyra::applyOp;
346 
347  assertInitialized();
348 
349 #ifdef TEUCHOS_DEBUG
350  for ( int j = 0; j < multi_vecs_in.size(); ++j ) {
352  "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
353  *this->range(), *multi_vecs_in[j]->range()
354  );
356  "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
357  *this->domain(), *multi_vecs_in[j]->domain()
358  );
359  }
360  for ( int j = 0; j < targ_multi_vecs_inout.size(); ++j ) {
362  "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
363  *this->range(), *targ_multi_vecs_inout[j]->range()
364  );
366  "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
367  *this->domain(), *targ_multi_vecs_inout[j]->domain()
368  );
369  }
370 #endif // TEUCHOS_DEBUG
371 
372  //
373  // Try to dynamic cast all of the multi-vector objects to the
374  // ProductMultiVectoBase interface.
375  //
376 
377  bool allProductMultiVectors = true;
378 
379  Array<Ptr<const ProductMultiVectorBase<Scalar> > > multi_vecs;
380  for ( int j = 0; j < multi_vecs_in.size() && allProductMultiVectors; ++j ) {
381 #ifdef TEUCHOS_DEBUG
382  TEUCHOS_TEST_FOR_EXCEPT( is_null(multi_vecs_in[j]) );
383 #endif
384  const Ptr<const ProductMultiVectorBase<Scalar> >
385  multi_vecs_j = ptr_dynamic_cast<const ProductMultiVectorBase<Scalar> >(
386  multi_vecs_in[j]
387  );
388  if ( !is_null(multi_vecs_j) ) {
389  multi_vecs.push_back(multi_vecs_j);
390  }
391  else {
392  allProductMultiVectors = false;
393  }
394  }
395 
396  Array<Ptr<ProductMultiVectorBase<Scalar> > > targ_multi_vecs;
397  for ( int j = 0; j < targ_multi_vecs_inout.size() && allProductMultiVectors; ++j )
398  {
399 #ifdef TEUCHOS_DEBUG
400  TEUCHOS_TEST_FOR_EXCEPT( is_null(targ_multi_vecs_inout[j]) );
401 #endif
402  Ptr<ProductMultiVectorBase<Scalar> >
403  targ_multi_vecs_j = ptr_dynamic_cast<ProductMultiVectorBase<Scalar> >(
404  targ_multi_vecs_inout[j]
405  );
406  if (!is_null(targ_multi_vecs_j)) {
407  targ_multi_vecs.push_back(targ_multi_vecs_j);
408  }
409  else {
410  allProductMultiVectors = false;
411  }
412  }
413 
414  //
415  // Do the reduction operations
416  //
417 
418  if ( allProductMultiVectors ) {
419 
420  // All of the multi-vector objects support the ProductMultiVectorBase
421  // interface so we can do the reductions block by block. Note, this is
422  // not the most efficient implementation in an SPMD program but this is
423  // easy to code up and use!
424 
425  // We must set up temporary arrays for the pointers to the MultiVectorBase
426  // blocks for each block of objects! What a mess!
427  Array<RCP<const MultiVectorBase<Scalar> > >
428  multi_vecs_rcp_block_k(multi_vecs_in.size());
429  Array<Ptr<const MultiVectorBase<Scalar> > >
430  multi_vecs_block_k(multi_vecs_in.size());
431  Array<RCP<MultiVectorBase<Scalar> > >
432  targ_multi_vecs_rcp_block_k(targ_multi_vecs_inout.size());
433  Array<Ptr<MultiVectorBase<Scalar> > >
434  targ_multi_vecs_block_k(targ_multi_vecs_inout.size());
435 
436  Ordinal g_off = primary_global_offset_in;
437 
438  for ( int k = 0; k < numBlocks_; ++k ) {
439 
440  const Ordinal dim_k = productSpace_->getBlock(k)->dim();
441 
442  // Fill the MultiVector array objects for this block
443 
444  for ( int j = 0; j < multi_vecs_in.size(); ++j ) {
445  RCP<const MultiVectorBase<Scalar> > multi_vecs_rcp_block_k_j =
446  multi_vecs[j]->getMultiVectorBlock(k);
447  multi_vecs_rcp_block_k[j] = multi_vecs_rcp_block_k_j;
448  multi_vecs_block_k[j] = multi_vecs_rcp_block_k_j.ptr();
449  }
450 
451  for ( int j = 0; j < targ_multi_vecs_inout.size(); ++j ) {
452  RCP<MultiVectorBase<Scalar> > targ_multi_vecs_rcp_block_k_j =
453  targ_multi_vecs[j]->getNonconstMultiVectorBlock(k);
454  targ_multi_vecs_rcp_block_k[j] = targ_multi_vecs_rcp_block_k_j;
455  targ_multi_vecs_block_k[j] = targ_multi_vecs_rcp_block_k_j.ptr();
456  }
457 
458  // Apply the RTOp object to the MultiVectors for this block
459 
460  Thyra::applyOp<Scalar>(
461  primary_op, multi_vecs_block_k(), targ_multi_vecs_block_k(),
462  reduct_objs,
463  g_off
464  );
465 
466  g_off += dim_k;
467  }
468 
469  }
470  else {
471 
472  // All of the multi-vector objects do not support the
473  // ProductMultiVectorBase interface but if we got here (in debug mode)
474  // then the spaces said that they are compatible so fall back on the
475  // column-by-column implementation that will work correctly in serial.
476 
478  primary_op, multi_vecs_in(), targ_multi_vecs_inout(),
479  reduct_objs, primary_global_offset_in);
480 
481  }
482 
483 }
484 
485 
486 template<class Scalar>
488  const Range1D &rowRng,
489  const Range1D &colRng,
491  ) const
492 {
494  rowRng, colRng, sub_mv );
495  // ToDo: Override this implementation if needed!
496 }
497 
498 
499 template<class Scalar>
502  ) const
503 {
505  sub_mv );
506  // ToDo: Override this implementation if needed!
507 }
508 
509 
510 template<class Scalar>
512  const Range1D &rowRng,
513  const Range1D &colRng,
515  )
516 {
518  rowRng,colRng,sub_mv );
519  // ToDo: Override this implementation if needed!
520 }
521 
522 
523 template<class Scalar>
526  )
527 {
529  // ToDo: Override this implementation if needed!
530 }
531 
532 
533 // Overridden protected functions from LinearOpBase
534 
535 
536 template<class Scalar>
538 {
539  return true; // We can do it all!
540 }
541 
542 
543 template<class Scalar>
545  const EOpTransp M_trans,
546  const MultiVectorBase<Scalar> &X_in,
547  const Ptr<MultiVectorBase<Scalar> > &Y_inout,
548  const Scalar alpha,
549  const Scalar beta
550  ) const
551 {
552 
553  typedef Teuchos::ScalarTraits<Scalar> ST;
554  using Teuchos::dyn_cast;
555  using Thyra::apply;
556 
557 #ifdef TEUCHOS_DEBUG
559  "DefaultProductMultiVector<Scalar>::apply(...)",
560  *this, M_trans, X_in, &*Y_inout );
561 #endif
562 
563  if ( real_trans(M_trans) == NOTRANS ) {
564  //
565  // Y = b*Y + a*M*X
566  //
567  // =>
568  //
569  // Y[k] = b*Y[k] + a*M[k]*X, k = 0...numBlocks-1
570  //
572  &Y = dyn_cast<ProductMultiVectorBase<Scalar> >(*Y_inout);
573  for ( int k = 0; k < numBlocks_; ++k ) {
574  Thyra::apply(
575  *multiVecs_[k].getConstObj(), M_trans,
576  X_in, Y.getNonconstMultiVectorBlock(k).ptr(),
577  alpha, beta );
578  }
579  }
580  else {
581  //
582  // Y = b*Y + a*trans(M)*X
583  //
584  // =>
585  //
586  // Y = b*Y + sum( a * trans(M[k]) * X[k], k=0...numBlocks-1 )
587  //
589  &X = dyn_cast<const ProductMultiVectorBase<Scalar> >(X_in);
590  for ( int k = 0; k < numBlocks_; ++k ) {
591  RCP<const MultiVectorBase<Scalar> >
592  M_k = multiVecs_[k].getConstObj(),
593  X_k = X.getMultiVectorBlock(k);
594  if ( 0 == k ) {
595  Thyra::apply( *M_k, M_trans, *X_k, Y_inout.ptr(), alpha, beta );
596  }
597  else {
598  Thyra::apply( *M_k, M_trans, *X_k, Y_inout.ptr(), alpha, ST::one() );
599  }
600  }
601  }
602 }
603 
604 
605 // private
606 
607 
608 template<class Scalar>
609 template<class MultiVectorType>
611  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
612  const ArrayView<const RCP<MultiVectorType> > &multiVecs
613  )
614 {
615  // This function provides the "strong" guarantee (i.e. if an exception is
616  // thrown, then *this will be left in the original state as before the
617  // function was called)!
618 #ifdef TEUCHOS_DEBUG
619  TEUCHOS_ASSERT(nonnull(productSpace_in));
620  TEUCHOS_ASSERT_EQUALITY(multiVecs.size(), productSpace_in->numBlocks());
621 #endif // TEUCHOS_DEBUG
622  const RCP<const VectorSpaceBase<Scalar> >
623  theDomain = multiVecs[0]->domain();
624  const int numBlocks = productSpace_in->numBlocks();
625 #ifdef TEUCHOS_DEBUG
626  for ( int k = 0; k < numBlocks; ++k ) {
628  Teuchos::TypeNameTraits<DefaultProductMultiVector<Scalar> >::name(),
629  *theDomain, *multiVecs[k]->domain()
630  );
631  }
632 #endif
633  productSpace_ = productSpace_in;
634  numBlocks_ = numBlocks;
635  multiVecs_.assign(multiVecs.begin(),multiVecs.end());
636 }
637 
638 
639 #ifdef TEUCHOS_DEBUG
640 
641 
642 template<class Scalar>
643 void DefaultProductMultiVector<Scalar>::assertInitialized() const
644 {
645  TEUCHOS_TEST_FOR_EXCEPTION(
646  is_null(productSpace_), std::logic_error,
647  "Error, this DefaultProductMultiVector object is not intialized!"
648  );
649 }
650 
651 
652 template<class Scalar>
653 void DefaultProductMultiVector<Scalar>::validateColIndex(const int j) const
654 {
655  assertInitialized();
656  const int domainDim = multiVecs_[0].getConstObj()->domain()->dim();
657  TEUCHOS_TEST_FOR_EXCEPTION(
658  ! ( 0 <= j && j < domainDim ), std::logic_error,
659  "Error, the column index j = " << j << " does not fall in the range [0,"<<domainDim<<"]!"
660  );
661 }
662 
663 
664 #endif // TEUCHOS_DEBUG
665 
666 
667 } // namespace Thyra
668 
669 
670 template<class Scalar>
671 Teuchos::RCP<Thyra::DefaultProductMultiVector<Scalar> >
672 Thyra::defaultProductMultiVector()
673 {
674  return Teuchos::rcp(new DefaultProductMultiVector<Scalar>);
675 }
676 
677 
678 template<class Scalar>
679 Teuchos::RCP<Thyra::DefaultProductMultiVector<Scalar> >
680 Thyra::defaultProductMultiVector(
681  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
682  const int numMembers
683  )
684 {
685  RCP<DefaultProductMultiVector<Scalar> > pmv = defaultProductMultiVector<Scalar>();
686  pmv->initialize(productSpace, numMembers);
687  return pmv;
688 }
689 
690 
691 template<class Scalar>
692 Teuchos::RCP<Thyra::DefaultProductMultiVector<Scalar> >
693 Thyra::defaultProductMultiVector(
694  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
695  const ArrayView<const RCP<MultiVectorBase<Scalar> > > &multiVecs
696  )
697 {
698  const RCP<DefaultProductMultiVector<Scalar> > pmv =
699  defaultProductMultiVector<Scalar>();
700  pmv->initialize(productSpace, multiVecs);
701  return pmv;
702 }
703 
704 
705 template<class Scalar>
706 Teuchos::RCP<Thyra::DefaultProductMultiVector<Scalar> >
707 Thyra::defaultProductMultiVector(
708  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
709  const ArrayView<const RCP<const MultiVectorBase<Scalar> > > &multiVecs
710  )
711 {
712  const RCP<DefaultProductMultiVector<Scalar> > pmv =
713  defaultProductMultiVector<Scalar>();
714  pmv->initialize(productSpace, multiVecs);
715  return pmv;
716 }
717 
718 
719 template<class Scalar>
720 Teuchos::RCP<const Thyra::ProductMultiVectorBase<Scalar> >
721 Thyra::castOrCreateSingleBlockProductMultiVector(
722  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
723  const RCP<const MultiVectorBase<Scalar> > &mv
724  )
725 {
726  const RCP<const ProductMultiVectorBase<Scalar> > pmv =
727  Teuchos::rcp_dynamic_cast<const ProductMultiVectorBase<Scalar> >(mv);
728  if (nonnull(pmv))
729  return pmv;
730  return defaultProductMultiVector<Scalar>(productSpace, Teuchos::tuple(mv)());
731 }
732 
733 
734 template<class Scalar>
735 Teuchos::RCP<Thyra::ProductMultiVectorBase<Scalar> >
736 Thyra::nonconstCastOrCreateSingleBlockProductMultiVector(
737  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
738  const RCP<MultiVectorBase<Scalar> > &mv
739  )
740 {
741  const RCP<ProductMultiVectorBase<Scalar> > pmv =
742  Teuchos::rcp_dynamic_cast<ProductMultiVectorBase<Scalar> >(mv);
743  if (nonnull(pmv))
744  return pmv;
745  return defaultProductMultiVector<Scalar>(productSpace, Teuchos::tuple(mv)());
746 }
747 
748 
749 //
750 // Explicit instantiation macro
751 //
752 // Must be expanded from within the Thyra namespace!
753 //
754 
755 
756 #define THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_INSTANT(SCALAR) \
757  \
758  template class DefaultProductMultiVector<SCALAR >; \
759  \
760  template RCP<DefaultProductMultiVector<SCALAR > > \
761  defaultProductMultiVector<SCALAR >(); \
762  \
763  \
764  template RCP<DefaultProductMultiVector<SCALAR > > \
765  defaultProductMultiVector( \
766  const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
767  const int numMembers \
768  ); \
769  \
770  \
771  template RCP<DefaultProductMultiVector<SCALAR > > \
772  defaultProductMultiVector( \
773  const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
774  const ArrayView<const RCP<MultiVectorBase<SCALAR > > > &multiVecs \
775  ); \
776  \
777  \
778  template RCP<DefaultProductMultiVector<SCALAR > > \
779  defaultProductMultiVector( \
780  const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
781  const ArrayView<const RCP<const MultiVectorBase<SCALAR > > > &multiVecs \
782  ); \
783  \
784  \
785  template RCP<const ProductMultiVectorBase<SCALAR > > \
786  castOrCreateSingleBlockProductMultiVector( \
787  const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
788  const RCP<const MultiVectorBase<SCALAR > > &mv \
789  ); \
790  \
791  \
792  template RCP<ProductMultiVectorBase<SCALAR > > \
793  nonconstCastOrCreateSingleBlockProductMultiVector( \
794  const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
795  const RCP<MultiVectorBase<SCALAR > > &mv \
796  );
797 
798 
799 #endif // THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_DEF_HPP
Base interface for product multi-vectors.
#define THYRA_ASSERT_VEC_SPACES(FUNC_NAME, VS1, VS2)
This is a very useful macro that should be used to validate that two vector spaces are compatible...
virtual void mvMultiReductApplyOpImpl(const RTOpPack::RTOpT< Scalar > &primary_op, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &multi_vecs, const ArrayView< const Ptr< MultiVectorBase< Scalar > > > &targ_multi_vecs, const ArrayView< const Ptr< RTOpPack::ReductTarget > > &reduct_objs, const Ordinal primary_global_offset) const
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
void releaseDetachedMultiVectorViewImpl(RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
#define THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(FUNC_NAME, M, M_T, X, Y)
This is a very useful macro that should be used to validate that the spaces for the multi-vector vers...
void mvMultiReductApplyOpImpl(const RTOpPack::RTOpT< Scalar > &primary_op, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &multi_vecs, const ArrayView< const Ptr< MultiVectorBase< Scalar > > > &targ_multi_vecs, const ArrayView< const Ptr< RTOpPack::ReductTarget > > &reduct_objs, const Ordinal primary_global_offset) const
RCP< const MultiVectorBase< Scalar > > getMultiVectorBlock(const int k) const
virtual void acquireNonconstDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
RCP< const VectorBase< Scalar > > colImpl(Ordinal j) const
Use the non-transposed operator.
RCP< VectorBase< Scalar > > nonconstColImpl(Ordinal j)
virtual Teuchos::RCP< MultiVectorBase< Scalar > > getNonconstMultiVectorBlock(const int k)=0
Returns a non-persisting non-const view of the zero-based kth block multi-vector. ...
EOpTransp real_trans(EOpTransp transp)
Return NOTRANS or TRANS for real scalar valued operators and this also is used for determining struct...
RCP< const MultiVectorBase< Scalar > > contigSubViewImpl(const Range1D &colRng) const
RCP< const MultiVectorBase< Scalar > > nonContigSubViewImpl(const ArrayView< const int > &cols) const
void applyImpl(const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const
virtual Teuchos::RCP< const MultiVectorBase< Scalar > > getMultiVectorBlock(const int k) const =0
Returns a non-persisting const view of the (zero-based) kth block multi-vector.
virtual void releaseDetachedMultiVectorViewImpl(RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
RCP< MultiVectorBase< Scalar > > getNonconstMultiVectorBlock(const int k)
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
void acquireNonconstDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
RCP< const ProductVectorSpaceBase< Scalar > > productSpace() const
Interface for a collection of column vectors called a multi-vector.
RCP< MultiVectorBase< Scalar > > nonconstContigSubViewImpl(const Range1D &colRng)
virtual void acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
Concrete implementation of a product multi-vector.
RCP< MultiVectorBase< Scalar > > clone_mv() const
virtual void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
RCP< const VectorSpaceBase< Scalar > > range() const
void acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
void initialize(const RCP< const DefaultProductVectorSpace< Scalar > > &productSpace, const int numMembers)
RCP< const VectorSpaceBase< Scalar > > domain() const
RCP< MultiVectorBase< Scalar > > nonconstNonContigSubViewImpl(const ArrayView< const int > &cols)
Teuchos::Range1D Range1D