Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thyra_DefaultProductMultiVector_def.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
4 //
5 // Copyright 2004 NTESS and the Thyra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_DEF_HPP
11 #define THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_DEF_HPP
12 
13 #include "Thyra_DefaultProductMultiVector_decl.hpp"
14 #include "Thyra_DefaultProductVectorSpace.hpp"
15 #include "Thyra_DefaultProductVector.hpp"
16 #include "Thyra_AssertOp.hpp"
17 
18 
19 namespace Thyra {
20 
21 
22 // Constructors/initializers/accessors
23 
24 
25 template<class Scalar>
27  :numBlocks_(0)
28 {}
29 
30 
31 template<class Scalar>
33  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
34  const int numMembers
35  )
36 {
37 #ifdef TEUCHOS_DEBUG
38  TEUCHOS_TEST_FOR_EXCEPT( is_null(productSpace_in) );
39  TEUCHOS_TEST_FOR_EXCEPT( numMembers <= 0 );
40 #endif
42  const int numBlocks = productSpace_in->numBlocks();
43  for ( int k = 0; k < numBlocks; ++k )
44  multiVecs.push_back(createMembers(productSpace_in->getBlock(k),numMembers));
45  initialize(productSpace_in,multiVecs);
46 }
47 
48 
49 template<class Scalar>
51  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
52  const ArrayView<const RCP<MultiVectorBase<Scalar> > > &multiVecs
53  )
54 {
55  initializeImpl(productSpace_in,multiVecs);
56 }
57 
58 
59 template<class Scalar>
61  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
62  const ArrayView<const RCP<const MultiVectorBase<Scalar> > > &multiVecs
63  )
64 {
65  initializeImpl(productSpace_in,multiVecs);
66 }
67 
68 
69 template<class Scalar>
71 {
72  productSpace_ = Teuchos::null;
73  multiVecs_.resize(0);
74  numBlocks_ = 0;
75 }
76 
77 
78 // Overridden public functions from Teuchos::Describable
79 
80 
81 template<class Scalar>
83 {
84  std::ostringstream oss;
85  oss
87  << "{"
88  << "rangeDim="<<this->range()->dim()
89  << ",domainDim="<<this->domain()->dim()
90  << ",numBlocks = "<<numBlocks_
91  << "}";
92  return oss.str();
93 }
94 
95 
96 template<class Scalar>
98  FancyOStream &out_arg,
99  const Teuchos::EVerbosityLevel verbLevel
100  ) const
101 {
102  using Teuchos::OSTab;
103  using Teuchos::describe;
104  if (verbLevel == Teuchos::VERB_NONE)
105  return;
106  RCP<FancyOStream> out = rcp(&out_arg,false);
107  OSTab tab(out);
108  switch(verbLevel) {
109  case Teuchos::VERB_NONE:
110  break;
111  case Teuchos::VERB_DEFAULT: // fall through
112  case Teuchos::VERB_LOW: // fall through
113  *out << this->description() << std::endl;
114  break;
115  case Teuchos::VERB_MEDIUM: // fall through
116  case Teuchos::VERB_HIGH: // fall through
118  {
119  *out
121  << "rangeDim="<<this->range()->dim()
122  << ",domainDim="<<this->domain()->dim()
123  << "}\n";
124  OSTab tab2(out);
125  *out
126  << "numBlocks="<< numBlocks_ << std::endl
127  << "Constituent multi-vector objects V[0], V[1], ... V[numBlocks-1]:\n";
128  OSTab tab3(out);
129  for( int k = 0; k < numBlocks_; ++k ) {
130  *out << "V["<<k<<"] = "
131  << Teuchos::describe(*multiVecs_[k].getConstObj(),verbLevel);
132  }
133  break;
134  }
135  default:
136  TEUCHOS_TEST_FOR_EXCEPT(true); // Should never get here!
137  }
138 }
139 
140 
141 // Overridden public functions from ProductMultiVectorBase
142 
143 
144 template<class Scalar>
147 {
148  return productSpace_;
149 }
150 
151 
152 template<class Scalar>
154 {
155  return multiVecs_[k].isConst();
156 }
157 
158 
159 template<class Scalar>
162 {
163  return multiVecs_[k].getNonconstObj();
164 }
165 
166 
167 template<class Scalar>
170 {
171  return multiVecs_[k].getConstObj();
172 }
173 
174 
175 // Overridden public functions from MultiVectorBase
176 
177 
178 template<class Scalar>
181 {
182  assertInitialized();
184  for ( int k = 0; k < numBlocks_; ++k )
185  blocks.push_back(multiVecs_[k].getConstObj()->clone_mv());
186  return defaultProductMultiVector<Scalar>(productSpace_, blocks());
187 }
188 
189 
190 // Overriden public functions from LinearOpBase
191 
192 
193 template<class Scalar>
196 {
197  return productSpace_;
198 }
199 
200 
201 template<class Scalar>
204 {
205  if (is_null(productSpace_))
206  return Teuchos::null;
207  return multiVecs_[0].getConstObj()->domain();
208 }
209 
210 
211 // protected
212 
213 
214 // Overriden protected functions from MultiVectorBase
215 
216 
217 template<class Scalar>
219 {
220  for ( int k = 0; k < numBlocks_; ++k ) {
221  multiVecs_[k].getNonconstObj()->assign(alpha);
222  }
223 }
224 
225 
226 template<class Scalar>
228  const MultiVectorBase<Scalar>& mv
229  )
230 {
231 #ifdef TEUCHOS_DEBUG
232  TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), mv.domain()->dim());
233  TEUCHOS_ASSERT(productSpace_->isCompatible(*mv.range()));
234 #endif
235 
236  // Apply operation block-by-block if mv is also a ProductMultiVector
238  = Teuchos::rcp_dynamic_cast<const ProductMultiVectorBase<Scalar> >(Teuchos::rcpFromRef(mv));
239  if (nonnull(pv)) {
240  for (int k = 0; k < numBlocks_; ++k) {
241  multiVecs_[k].getNonconstObj()->assign(*pv->getMultiVectorBlock(k));
242  }
243  } else {
245  }
246 }
247 
248 
249 template<class Scalar>
251 {
252  for (int k = 0; k < numBlocks_; ++k) {
253  multiVecs_[k].getNonconstObj()->scale(alpha);
254  }
255 }
256 
257 
258 template<class Scalar>
260  Scalar alpha,
261  const MultiVectorBase<Scalar>& mv
262  )
263 {
264 #ifdef TEUCHOS_DEBUG
265  TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), mv.domain()->dim());
266  TEUCHOS_ASSERT(productSpace_->isCompatible(*mv.range()));
267 #endif
268 
269  // Apply operation block-by-block if mv is also a ProductMultiVector
271  = Teuchos::rcp_dynamic_cast<const ProductMultiVectorBase<Scalar> >(Teuchos::rcpFromRef(mv));
272  if (nonnull(pv)) {
273  for (int k = 0; k < numBlocks_; ++k) {
274  multiVecs_[k].getNonconstObj()->update(alpha, *pv->getMultiVectorBlock(k));
275  }
276  } else {
278  }
279 }
280 
281 
282 template<class Scalar>
284  const ArrayView<const Scalar>& alpha,
285  const ArrayView<const Ptr<const MultiVectorBase<Scalar> > >& mv,
286  const Scalar& beta
287  )
288 {
289 #ifdef TEUCHOS_DEBUG
290  TEUCHOS_ASSERT_EQUALITY(alpha.size(), mv.size());
291  for (Ordinal i = 0; i < mv.size(); ++i) {
292  TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), mv[i]->domain()->dim());
293  TEUCHOS_ASSERT(productSpace_->isCompatible(*mv[i]->range()));
294  }
295 #endif
296 
297  // Apply operation block-by-block if each element of mv is also a ProductMultiVector
298  bool allCastsSuccessful = true;
300  for (Ordinal i = 0; i < mv.size(); ++i) {
301  pvs[i] = Teuchos::ptr_dynamic_cast<const ProductMultiVectorBase<Scalar> >(mv[i]);
302  if (pvs[i].is_null()) {
303  allCastsSuccessful = false;
304  break;
305  }
306  }
307 
308  if (allCastsSuccessful) {
309  Array<RCP<const MultiVectorBase<Scalar> > > blocks_rcp(pvs.size());
310  Array<Ptr<const MultiVectorBase<Scalar> > > blocks(pvs.size());
311  for (int k = 0; k < numBlocks_; ++k) {
312  for (Ordinal i = 0; i < pvs.size(); ++i) {
313  blocks_rcp[i] = pvs[i]->getMultiVectorBlock(k);
314  blocks[i] = blocks_rcp[i].ptr();
315  }
316  multiVecs_[k].getNonconstObj()->linear_combination(alpha, blocks(), beta);
317  }
318  } else {
320  }
321 }
322 
323 
324 template<class Scalar>
326  const MultiVectorBase<Scalar>& mv,
327  const ArrayView<Scalar>& prods
328  ) const
329 {
330 #ifdef TEUCHOS_DEBUG
331  TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), mv.domain()->dim());
332  TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), prods.size());
333  TEUCHOS_ASSERT(productSpace_->isCompatible(*mv.range()));
334 #endif
335  // Apply operation block-by-block if mv is also a ProductMultiVector
337  = Teuchos::rcp_dynamic_cast<const ProductMultiVectorBase<Scalar> >(Teuchos::rcpFromRef(mv));
338  if (nonnull(pv)) {
339  for (Ordinal i = 0; i < prods.size(); ++i)
340  prods[i] = ScalarTraits<Scalar>::zero();
341 
342  Array<Scalar> subProds(prods.size());
343  for (int k = 0; k < numBlocks_; ++k) {
344  multiVecs_[k].getConstObj()->dots(*pv->getMultiVectorBlock(k), subProds());
345  for (Ordinal i = 0; i < prods.size(); ++i) {
346  prods[i] += subProds[i];
347  }
348  }
349  } else {
351  }
352 }
353 
354 
355 template<class Scalar>
357  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
358  ) const
359 {
360 #ifdef TEUCHOS_DEBUG
361  TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), norms.size());
362 #endif
363  typedef ScalarTraits<Scalar> ST;
364  for (Ordinal i = 0; i < norms.size(); ++i)
365  norms[i] = ST::magnitude(ST::zero());
366 
367  Array<typename ST::magnitudeType> subNorms(norms.size());
368  for (int k = 0; k < numBlocks_; ++k) {
369  multiVecs_[k].getConstObj()->norms_1(subNorms());
370  for (Ordinal i = 0; i < norms.size(); ++i) {
371  norms[i] += subNorms[i];
372  }
373  }
374 }
375 
376 
377 template<class Scalar>
379  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
380  ) const
381 {
382 #ifdef TEUCHOS_DEBUG
383  TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), norms.size());
384 #endif
385  typedef ScalarTraits<Scalar> ST;
386  for (Ordinal i = 0; i < norms.size(); ++i)
387  norms[i] = ST::magnitude(ST::zero());
388 
389  Array<typename ST::magnitudeType> subNorms(norms.size());
390  for (int k = 0; k < numBlocks_; ++k) {
391  multiVecs_[k].getConstObj()->norms_2(subNorms());
392  for (Ordinal i = 0; i < norms.size(); ++i) {
393  norms[i] += subNorms[i]*subNorms[i];
394  }
395  }
396 
397  for (Ordinal i = 0; i < norms.size(); ++i) {
398  norms[i] = ST::magnitude(ST::squareroot(norms[i]));
399  }
400 }
401 
402 
403 template<class Scalar>
405  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
406  ) const
407 {
408 #ifdef TEUCHOS_DEBUG
409  TEUCHOS_ASSERT_EQUALITY(this->domain()->dim(), norms.size());
410 #endif
411  typedef ScalarTraits<Scalar> ST;
412  for (Ordinal i = 0; i < norms.size(); ++i)
413  norms[i] = ST::magnitude(ST::zero());
414 
415  Array<typename ST::magnitudeType> subNorms(norms.size());
416  for (int k = 0; k < numBlocks_; ++k) {
417  multiVecs_[k].getConstObj()->norms_inf(subNorms());
418  for (Ordinal i = 0; i < norms.size(); ++i) {
419  if (subNorms[i] > norms[i])
420  norms[i] = subNorms[i];
421  }
422  }
423 }
424 
425 
426 template<class Scalar>
429 {
430  validateColIndex(j);
432  for ( int k = 0; k < numBlocks_; ++k )
433  cols_.push_back(multiVecs_[k].getConstObj()->col(j));
434  return defaultProductVector<Scalar>(productSpace_, cols_());
435 }
436 
437 
438 template<class Scalar>
441 {
442  validateColIndex(j);
444  for ( int k = 0; k < numBlocks_; ++k )
445  cols_.push_back(multiVecs_[k].getNonconstObj()->col(j));
446  return defaultProductVector<Scalar>(productSpace_, cols_());
447 }
448 
449 
450 template<class Scalar>
453 {
454  assertInitialized();
456  for ( int k = 0; k < numBlocks_; ++k )
457  blocks.push_back(multiVecs_[k].getConstObj()->subView(colRng));
458  return defaultProductMultiVector<Scalar>(productSpace_, blocks());
459 }
460 
461 
462 template<class Scalar>
465 {
466  assertInitialized();
468  for ( int k = 0; k < numBlocks_; ++k )
469  blocks.push_back(multiVecs_[k].getNonconstObj()->subView(colRng));
470  return defaultProductMultiVector<Scalar>(productSpace_, blocks());
471 }
472 
473 
474 template<class Scalar>
477  const ArrayView<const int> &cols
478  ) const
479 {
480  assertInitialized();
482  for ( int k = 0; k < numBlocks_; ++k )
483  blocks.push_back(multiVecs_[k].getConstObj()->subView(cols));
484  return defaultProductMultiVector<Scalar>(productSpace_, blocks());
485 }
486 
487 
488 template<class Scalar>
491  const ArrayView<const int> &cols
492  )
493 {
494  assertInitialized();
496  for ( int k = 0; k < numBlocks_; ++k )
497  blocks.push_back(multiVecs_[k].getNonconstObj()->subView(cols));
498  return defaultProductMultiVector<Scalar>(productSpace_, blocks());
499 }
500 
501 
502 template<class Scalar>
504  const RTOpPack::RTOpT<Scalar> &primary_op,
505  const ArrayView<const Ptr<const MultiVectorBase<Scalar> > > &multi_vecs_in,
506  const ArrayView<const Ptr<MultiVectorBase<Scalar> > > &targ_multi_vecs_inout,
507  const ArrayView<const Ptr<RTOpPack::ReductTarget> > &reduct_objs,
508  const Ordinal primary_global_offset_in
509  ) const
510 {
511 
512  using Teuchos::ptr_dynamic_cast;
513  using Thyra::applyOp;
514 
515  assertInitialized();
516 
517 #ifdef TEUCHOS_DEBUG
518  for ( int j = 0; j < multi_vecs_in.size(); ++j ) {
520  "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
521  *this->range(), *multi_vecs_in[j]->range()
522  );
524  "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
525  *this->domain(), *multi_vecs_in[j]->domain()
526  );
527  }
528  for ( int j = 0; j < targ_multi_vecs_inout.size(); ++j ) {
530  "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
531  *this->range(), *targ_multi_vecs_inout[j]->range()
532  );
534  "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
535  *this->domain(), *targ_multi_vecs_inout[j]->domain()
536  );
537  }
538 #endif // TEUCHOS_DEBUG
539 
540  //
541  // Try to dynamic cast all of the multi-vector objects to the
542  // ProductMultiVectoBase interface.
543  //
544 
545  bool allProductMultiVectors = true;
546 
548  for ( int j = 0; j < multi_vecs_in.size() && allProductMultiVectors; ++j ) {
549 #ifdef TEUCHOS_DEBUG
550  TEUCHOS_TEST_FOR_EXCEPT( is_null(multi_vecs_in[j]) );
551 #endif
553  multi_vecs_j = ptr_dynamic_cast<const ProductMultiVectorBase<Scalar> >(
554  multi_vecs_in[j]
555  );
556  if ( !is_null(multi_vecs_j) ) {
557  multi_vecs.push_back(multi_vecs_j);
558  }
559  else {
560  allProductMultiVectors = false;
561  }
562  }
563 
564  Array<Ptr<ProductMultiVectorBase<Scalar> > > targ_multi_vecs;
565  for ( int j = 0; j < targ_multi_vecs_inout.size() && allProductMultiVectors; ++j )
566  {
567 #ifdef TEUCHOS_DEBUG
568  TEUCHOS_TEST_FOR_EXCEPT( is_null(targ_multi_vecs_inout[j]) );
569 #endif
571  targ_multi_vecs_j = ptr_dynamic_cast<ProductMultiVectorBase<Scalar> >(
572  targ_multi_vecs_inout[j]
573  );
574  if (!is_null(targ_multi_vecs_j)) {
575  targ_multi_vecs.push_back(targ_multi_vecs_j);
576  }
577  else {
578  allProductMultiVectors = false;
579  }
580  }
581 
582  //
583  // Do the reduction operations
584  //
585 
586  if ( allProductMultiVectors ) {
587 
588  // All of the multi-vector objects support the ProductMultiVectorBase
589  // interface so we can do the reductions block by block. Note, this is
590  // not the most efficient implementation in an SPMD program but this is
591  // easy to code up and use!
592 
593  // We must set up temporary arrays for the pointers to the MultiVectorBase
594  // blocks for each block of objects! What a mess!
596  multi_vecs_rcp_block_k(multi_vecs_in.size());
598  multi_vecs_block_k(multi_vecs_in.size());
600  targ_multi_vecs_rcp_block_k(targ_multi_vecs_inout.size());
602  targ_multi_vecs_block_k(targ_multi_vecs_inout.size());
603 
604  Ordinal g_off = primary_global_offset_in;
605 
606  for ( int k = 0; k < numBlocks_; ++k ) {
607 
608  const Ordinal dim_k = productSpace_->getBlock(k)->dim();
609 
610  // Fill the MultiVector array objects for this block
611 
612  for ( int j = 0; j < multi_vecs_in.size(); ++j ) {
613  RCP<const MultiVectorBase<Scalar> > multi_vecs_rcp_block_k_j =
614  multi_vecs[j]->getMultiVectorBlock(k);
615  multi_vecs_rcp_block_k[j] = multi_vecs_rcp_block_k_j;
616  multi_vecs_block_k[j] = multi_vecs_rcp_block_k_j.ptr();
617  }
618 
619  for ( int j = 0; j < targ_multi_vecs_inout.size(); ++j ) {
620  RCP<MultiVectorBase<Scalar> > targ_multi_vecs_rcp_block_k_j =
621  targ_multi_vecs[j]->getNonconstMultiVectorBlock(k);
622  targ_multi_vecs_rcp_block_k[j] = targ_multi_vecs_rcp_block_k_j;
623  targ_multi_vecs_block_k[j] = targ_multi_vecs_rcp_block_k_j.ptr();
624  }
625 
626  // Apply the RTOp object to the MultiVectors for this block
627 
628  Thyra::applyOp<Scalar>(
629  primary_op, multi_vecs_block_k(), targ_multi_vecs_block_k(),
630  reduct_objs,
631  g_off
632  );
633 
634  g_off += dim_k;
635  }
636 
637  }
638  else {
639 
640  // All of the multi-vector objects do not support the
641  // ProductMultiVectorBase interface but if we got here (in debug mode)
642  // then the spaces said that they are compatible so fall back on the
643  // column-by-column implementation that will work correctly in serial.
644 
646  primary_op, multi_vecs_in(), targ_multi_vecs_inout(),
647  reduct_objs, primary_global_offset_in);
648 
649  }
650 
651 }
652 
653 
654 template<class Scalar>
656  const Range1D &rowRng,
657  const Range1D &colRng,
659  ) const
660 {
662  rowRng, colRng, sub_mv );
663  // ToDo: Override this implementation if needed!
664 }
665 
666 
667 template<class Scalar>
670  ) const
671 {
673  sub_mv );
674  // ToDo: Override this implementation if needed!
675 }
676 
677 
678 template<class Scalar>
680  const Range1D &rowRng,
681  const Range1D &colRng,
683  )
684 {
686  rowRng,colRng,sub_mv );
687  // ToDo: Override this implementation if needed!
688 }
689 
690 
691 template<class Scalar>
694  )
695 {
697  // ToDo: Override this implementation if needed!
698 }
699 
700 
701 // Overridden protected functions from LinearOpBase
702 
703 
704 template<class Scalar>
706 {
707  return true; // We can do it all!
708 }
709 
710 
711 template<class Scalar>
713  const EOpTransp M_trans,
714  const MultiVectorBase<Scalar> &X_in,
715  const Ptr<MultiVectorBase<Scalar> > &Y_inout,
716  const Scalar alpha,
717  const Scalar beta
718  ) const
719 {
720 
722  using Teuchos::dyn_cast;
723  using Thyra::apply;
724 
725 #ifdef TEUCHOS_DEBUG
727  "DefaultProductMultiVector<Scalar>::apply(...)",
728  *this, M_trans, X_in, &*Y_inout );
729 #endif
730 
731  if ( real_trans(M_trans) == NOTRANS ) {
732  //
733  // Y = b*Y + a*M*X
734  //
735  // =>
736  //
737  // Y[k] = b*Y[k] + a*M[k]*X, k = 0...numBlocks-1
738  //
740  &Y = dyn_cast<ProductMultiVectorBase<Scalar> >(*Y_inout);
741  for ( int k = 0; k < numBlocks_; ++k ) {
742  Thyra::apply(
743  *multiVecs_[k].getConstObj(), M_trans,
744  X_in, Y.getNonconstMultiVectorBlock(k).ptr(),
745  alpha, beta );
746  }
747  }
748  else {
749  //
750  // Y = b*Y + a*trans(M)*X
751  //
752  // =>
753  //
754  // Y = b*Y + sum( a * trans(M[k]) * X[k], k=0...numBlocks-1 )
755  //
757  &X = dyn_cast<const ProductMultiVectorBase<Scalar> >(X_in);
758  for ( int k = 0; k < numBlocks_; ++k ) {
760  M_k = multiVecs_[k].getConstObj(),
761  X_k = X.getMultiVectorBlock(k);
762  if ( 0 == k ) {
763  Thyra::apply( *M_k, M_trans, *X_k, Y_inout.ptr(), alpha, beta );
764  }
765  else {
766  Thyra::apply( *M_k, M_trans, *X_k, Y_inout.ptr(), alpha, ST::one() );
767  }
768  }
769  }
770 }
771 
772 
773 // private
774 
775 
776 template<class Scalar>
777 template<class MultiVectorType>
779  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
780  const ArrayView<const RCP<MultiVectorType> > &multiVecs
781  )
782 {
783  // This function provides the "strong" guarantee (i.e. if an exception is
784  // thrown, then *this will be left in the original state as before the
785  // function was called)!
786 #ifdef TEUCHOS_DEBUG
787  TEUCHOS_ASSERT(nonnull(productSpace_in));
788  TEUCHOS_ASSERT_EQUALITY(multiVecs.size(), productSpace_in->numBlocks());
789 #endif // TEUCHOS_DEBUG
791  theDomain = multiVecs[0]->domain();
792  const int numBlocks = productSpace_in->numBlocks();
793 #ifdef TEUCHOS_DEBUG
794  for ( int k = 0; k < numBlocks; ++k ) {
797  *theDomain, *multiVecs[k]->domain()
798  );
799  }
800 #endif
801  productSpace_ = productSpace_in;
802  numBlocks_ = numBlocks;
803  multiVecs_.assign(multiVecs.begin(),multiVecs.end());
804 }
805 
806 
807 #ifdef TEUCHOS_DEBUG
808 
809 
810 template<class Scalar>
811 void DefaultProductMultiVector<Scalar>::assertInitialized() const
812 {
814  is_null(productSpace_), std::logic_error,
815  "Error, this DefaultProductMultiVector object is not intialized!"
816  );
817 }
818 
819 
820 template<class Scalar>
821 void DefaultProductMultiVector<Scalar>::validateColIndex(const int j) const
822 {
823  assertInitialized();
824  const int domainDim = multiVecs_[0].getConstObj()->domain()->dim();
826  ! ( 0 <= j && j < domainDim ), std::logic_error,
827  "Error, the column index j = " << j << " does not fall in the range [0,"<<domainDim<<"]!"
828  );
829 }
830 
831 
832 #endif // TEUCHOS_DEBUG
833 
834 
835 } // namespace Thyra
836 
837 
838 template<class Scalar>
840 Thyra::defaultProductMultiVector()
841 {
842  return Teuchos::rcp(new DefaultProductMultiVector<Scalar>);
843 }
844 
845 
846 template<class Scalar>
848 Thyra::defaultProductMultiVector(
849  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
850  const int numMembers
851  )
852 {
853  RCP<DefaultProductMultiVector<Scalar> > pmv = defaultProductMultiVector<Scalar>();
854  pmv->initialize(productSpace, numMembers);
855  return pmv;
856 }
857 
858 
859 template<class Scalar>
861 Thyra::defaultProductMultiVector(
862  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
863  const ArrayView<const RCP<MultiVectorBase<Scalar> > > &multiVecs
864  )
865 {
866  const RCP<DefaultProductMultiVector<Scalar> > pmv =
867  defaultProductMultiVector<Scalar>();
868  pmv->initialize(productSpace, multiVecs);
869  return pmv;
870 }
871 
872 
873 template<class Scalar>
875 Thyra::defaultProductMultiVector(
876  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
877  const ArrayView<const RCP<const MultiVectorBase<Scalar> > > &multiVecs
878  )
879 {
880  const RCP<DefaultProductMultiVector<Scalar> > pmv =
881  defaultProductMultiVector<Scalar>();
882  pmv->initialize(productSpace, multiVecs);
883  return pmv;
884 }
885 
886 
887 template<class Scalar>
889 Thyra::castOrCreateSingleBlockProductMultiVector(
890  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
891  const RCP<const MultiVectorBase<Scalar> > &mv
892  )
893 {
894  const RCP<const ProductMultiVectorBase<Scalar> > pmv =
895  Teuchos::rcp_dynamic_cast<const ProductMultiVectorBase<Scalar> >(mv);
896  if (nonnull(pmv))
897  return pmv;
898  return defaultProductMultiVector<Scalar>(productSpace, Teuchos::tuple(mv)());
899 }
900 
901 
902 template<class Scalar>
904 Thyra::nonconstCastOrCreateSingleBlockProductMultiVector(
905  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
906  const RCP<MultiVectorBase<Scalar> > &mv
907  )
908 {
909  const RCP<ProductMultiVectorBase<Scalar> > pmv =
910  Teuchos::rcp_dynamic_cast<ProductMultiVectorBase<Scalar> >(mv);
911  if (nonnull(pmv))
912  return pmv;
913  return defaultProductMultiVector<Scalar>(productSpace, Teuchos::tuple(mv)());
914 }
915 
916 
917 //
918 // Explicit instantiation macro
919 //
920 // Must be expanded from within the Thyra namespace!
921 //
922 
923 
924 #define THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_INSTANT(SCALAR) \
925  \
926  template class DefaultProductMultiVector<SCALAR >; \
927  \
928  template RCP<DefaultProductMultiVector<SCALAR > > \
929  defaultProductMultiVector<SCALAR >(); \
930  \
931  \
932  template RCP<DefaultProductMultiVector<SCALAR > > \
933  defaultProductMultiVector( \
934  const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
935  const int numMembers \
936  ); \
937  \
938  \
939  template RCP<DefaultProductMultiVector<SCALAR > > \
940  defaultProductMultiVector( \
941  const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
942  const ArrayView<const RCP<MultiVectorBase<SCALAR > > > &multiVecs \
943  ); \
944  \
945  \
946  template RCP<DefaultProductMultiVector<SCALAR > > \
947  defaultProductMultiVector( \
948  const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
949  const ArrayView<const RCP<const MultiVectorBase<SCALAR > > > &multiVecs \
950  ); \
951  \
952  \
953  template RCP<const ProductMultiVectorBase<SCALAR > > \
954  castOrCreateSingleBlockProductMultiVector( \
955  const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
956  const RCP<const MultiVectorBase<SCALAR > > &mv \
957  ); \
958  \
959  \
960  template RCP<ProductMultiVectorBase<SCALAR > > \
961  nonconstCastOrCreateSingleBlockProductMultiVector( \
962  const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
963  const RCP<MultiVectorBase<SCALAR > > &mv \
964  );
965 
966 
967 #endif // THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_DEF_HPP
void initialize(int *argc, char ***argv)
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 updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
bool is_null(const boost::shared_ptr< T > &p)
virtual RCP< const VectorSpaceBase< Scalar > > range() const =0
Return a smart pointer for the range space for this operator.
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
virtual void releaseDetachedMultiVectorViewImpl(RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
basic_OSTab< char > OSTab
#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 acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
virtual void acquireNonconstDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
virtual void assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
Default implementation of assign(MV) using RTOps.
basic_FancyOStream< char > FancyOStream
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Use the non-transposed operator.
RCP< VectorBase< Scalar > > nonconstColImpl(Ordinal j)
T_To & dyn_cast(T_From &from)
size_type size() const
virtual void norms1Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
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
virtual void linearCombinationImpl(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &mv, const Scalar &beta)
Default implementation of linear_combination using RTOps.
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...
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) 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.
RCP< const VectorSpaceBase< Scalar > > range() const
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void norms2Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
RCP< const MultiVectorBase< Scalar > > nonContigSubViewImpl(const ArrayView< const int > &cols) const
void releaseDetachedMultiVectorViewImpl(RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
RCP< MultiVectorBase< Scalar > > getNonconstMultiVectorBlock(const int k)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
void acquireNonconstDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
Interface for a collection of column vectors called a multi-vector.
RCP< MultiVectorBase< Scalar > > nonconstContigSubViewImpl(const Range1D &colRng)
Ptr< T > ptr() const
Concrete implementation of a product multi-vector.
virtual void linearCombinationImpl(const ArrayView< const Scalar > &alpha, const ArrayView< const Ptr< const MultiVectorBase< Scalar > > > &mv, const Scalar &beta)
virtual void assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
void update(Scalar alpha, const MultiVectorBase< Scalar > &mv)
virtual std::string description() const
RCP< MultiVectorBase< Scalar > > clone_mv() const
virtual void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
virtual void normsInfImpl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
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
void assign(Scalar alpha)
V = alpha.
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
Return a smart pointer for the domain space for this operator.
bool nonnull(const boost::shared_ptr< T > &p)
void push_back(const value_type &x)
RCP< const VectorSpaceBase< Scalar > > domain() const
void commitNonconstDetachedMultiVectorViewImpl(RTOpPack::SubMultiVectorView< Scalar > *sub_mv)
void initialize(const RCP< const DefaultProductVectorSpace< Scalar > > &productSpace, const int numMembers)
RCP< const MultiVectorBase< Scalar > > getMultiVectorBlock(const int k) const
void applyImpl(const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const
RCP< const ProductVectorSpaceBase< Scalar > > productSpace() const
RCP< MultiVectorBase< Scalar > > nonconstNonContigSubViewImpl(const ArrayView< const int > &cols)
#define TEUCHOS_ASSERT(assertion_test)
virtual void acquireDetachedMultiVectorViewImpl(const Range1D &rowRng, const Range1D &colRng, RTOpPack::ConstSubMultiVectorView< Scalar > *sub_mv) const
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
RCP< const MultiVectorBase< Scalar > > contigSubViewImpl(const Range1D &colRng) const
RCP< const VectorBase< Scalar > > colImpl(Ordinal j) const
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) const
Default implementation of dots using RTOps.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
Default implementation of update using RTOps.