Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thyra_DefaultProductVector_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_VECTOR_DEF_HPP
11 #define THYRA_DEFAULT_PRODUCT_VECTOR_DEF_HPP
12 
13 
14 #include "Thyra_DefaultProductVector_decl.hpp"
15 #include "Thyra_DefaultProductVectorSpace.hpp"
16 #include "Teuchos_Workspace.hpp"
17 
18 
19 namespace Thyra {
20 
21 
22 // Constructors/initializers/accessors
23 
24 
25 template <class Scalar>
27  : numBlocks_(0)
28 {
29  uninitialize();
30 }
31 
32 
33 template <class Scalar>
35  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in
36  )
37  : numBlocks_(0)
38 {
39  initialize(productSpace_in);
40 }
41 
42 
43 template <class Scalar>
45  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in
46  )
47 {
48  // ToDo: Validate input!
49  numBlocks_ = productSpace_in->numBlocks();
50  productSpace_ = productSpace_in;
51  vecs_.resize(numBlocks_);
52  for( int k = 0; k < numBlocks_; ++k )
53  vecs_[k].initialize(createMember(productSpace_in->getBlock(k)));
54 }
55 
56 
57 template <class Scalar>
59  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
60  const ArrayView<const RCP<VectorBase<Scalar> > > &vecs
61  )
62 {
63  using Teuchos::as;
64 #ifdef TEUCHOS_DEBUG
65  TEUCHOS_ASSERT_EQUALITY( as<Ordinal>(productSpace_in->numBlocks()),
66  as<Ordinal>(vecs.size()) );
67 #endif
68  numBlocks_ = productSpace_in->numBlocks();
69  productSpace_ = productSpace_in;
70  vecs_.resize(numBlocks_);
71  for( int k = 0; k < numBlocks_; ++k )
72  vecs_[k].initialize(vecs[k]);
73 }
74 
75 
76 template <class Scalar>
78  const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
79  const ArrayView<const RCP<const VectorBase<Scalar> > > &vecs
80  )
81 {
82  using Teuchos::as;
83 #ifdef TEUCHOS_DEBUG
84  TEUCHOS_ASSERT_EQUALITY( as<Ordinal>(productSpace_in->numBlocks()),
85  as<Ordinal>(vecs.size()) );
86 #endif
87  numBlocks_ = productSpace_in->numBlocks();
88  productSpace_ = productSpace_in;
89  vecs_.resize(numBlocks_);
90  for( int k = 0; k < numBlocks_; ++k )
91  vecs_[k].initialize(vecs[k]);
92 }
93 
94 
95 template <class Scalar>
97 {
98  productSpace_ = Teuchos::null;
99  vecs_.resize(0);
100  numBlocks_ = 0;
101 }
102 
103 
104 // Overridden from Teuchos::Describable
105 
106 
107 template<class Scalar>
109 {
110  const RCP<const VectorSpaceBase<Scalar> > vs = this->space();
111  std::ostringstream oss;
112  oss
114  << "{"
115  << "dim="<<(nonnull(vs) ? vs->dim() : 0)
116  << ", numBlocks = "<<numBlocks_
117  << "}";
118  return oss.str();
119 }
120 
121 
122 template<class Scalar>
124  Teuchos::FancyOStream &out_arg,
125  const Teuchos::EVerbosityLevel verbLevel
126  ) const
127 {
128  using Teuchos::FancyOStream;
129  using Teuchos::OSTab;
130  using Teuchos::describe;
131  RCP<FancyOStream> out = rcp(&out_arg,false);
132  OSTab tab(out);
133  switch(verbLevel) {
134  case Teuchos::VERB_NONE:
135  break;
137  case Teuchos::VERB_LOW:
138  *out << this->description() << std::endl;
139  break;
141  case Teuchos::VERB_HIGH:
143  {
144  *out
146  << "dim=" << this->space()->dim()
147  << "}\n";
148  OSTab tab2(out);
149  *out
150  << "numBlocks="<< numBlocks_ << std::endl
151  << "Constituent vector objects v[0], v[1], ... v[numBlocks-1]:\n";
152  OSTab tab3(out);
153  for( int k = 0; k < numBlocks_; ++k ) {
154  *out << "v["<<k<<"] = " << describe(*vecs_[k].getConstObj(),verbLevel);
155  }
156  break;
157  }
158  default:
159  TEUCHOS_TEST_FOR_EXCEPT(true); // Should never get here!
160  }
161 }
162 
163 
164 // Extensions to ProductVectorBase suitable for physically-blocked vectors
165 
166 
167 template <class Scalar>
169  int i, const RCP<const VectorBase<Scalar> >& b
170  )
171 {
172 #ifdef TEUCHOS_DEBUG
173  TEUCHOS_TEST_FOR_EXCEPT(i < 0 || i >= numBlocks_);
174  TEUCHOS_TEST_FOR_EXCEPT(!productSpace_->getBlock(i)->isCompatible(*(b->space())));
175 #endif
176  vecs_[i] = b;
177 }
178 
179 
180 template <class Scalar>
182  int i, const RCP<VectorBase<Scalar> >& b
183  )
184 {
185 #ifdef TEUCHOS_DEBUG
186  TEUCHOS_TEST_FOR_EXCEPT(i < 0 || i >= numBlocks_);
187  TEUCHOS_TEST_FOR_EXCEPT(!productSpace_->getBlock(i)->isCompatible(*(b->space())));
188 #endif
189  vecs_[i] = b;
190 }
191 
192 
193 // Overridden from ProductVectorBase
194 
195 
196 template <class Scalar>
199 {
200 #ifdef TEUCHOS_DEBUG
201  TEUCHOS_TEST_FOR_EXCEPT( k < 0 || numBlocks_-1 < k);
202 #endif
203  return vecs_[k].getNonconstObj();
204 }
205 
206 
207 template <class Scalar>
210 {
211 #ifdef TEUCHOS_DEBUG
212  TEUCHOS_TEST_FOR_EXCEPT( k < 0 || numBlocks_-1 < k);
213 #endif
214  return vecs_[k].getConstObj();
215 }
216 
217 
218 // Overridden from ProductMultiVectorBase
219 
220 
221 template <class Scalar>
224 {
225  return productSpace_;
226 }
227 
228 
229 template <class Scalar>
231 {
232 #ifdef TEUCHOS_DEBUG
233  TEUCHOS_TEST_FOR_EXCEPT( k < 0 || numBlocks_-1 < k);
234 #endif
235  return vecs_[k].isConst();
236 }
237 
238 
239 template <class Scalar>
242 {
243  return getNonconstVectorBlock(k);
244 }
245 
246 
247 template <class Scalar>
250 {
251  return getVectorBlock(k);
252 }
253 
254 
255 // Overridden from VectorBase
256 
257 
258 template <class Scalar>
261 {
262  return productSpace_;
263 }
264 
265 
266 /*template <class Scalar>
267 void DefaultProductVector<Scalar>::randomizeImpl(
268  Scalar l,
269  Scalar u
270  )
271 {
272  for(int k = 0; k < numBlocks_; ++k) {
273  vecs_[k].getNonconstObj()->randomize(l, u);
274  }
275 }*/
276 
277 
278 template <class Scalar>
280  const VectorBase<Scalar>& x
281  )
282 {
283  // Apply operation block-by-block if mv is also a ProductVector
285  = Teuchos::rcp_dynamic_cast<const ProductVectorBase<Scalar> >(Teuchos::rcpFromRef(x));
286  if (nonnull(pv)) {
287 #ifdef TEUCHOS_DEBUG
288  TEUCHOS_ASSERT(productSpace_->isCompatible(*pv->productSpace()));
289 #endif
290  for(int k = 0; k < numBlocks_; ++k) {
291  vecs_[k].getNonconstObj()->abs(*pv->getVectorBlock(k));
292  }
293  } else {
295  }
296 }
297 
298 
299 template <class Scalar>
301  const VectorBase<Scalar>& x
302  )
303 {
304  // Apply operation block-by-block if mv is also a ProductVector
306  = Teuchos::rcp_dynamic_cast<const ProductVectorBase<Scalar> >(Teuchos::rcpFromRef(x));
307  if (nonnull(pv)) {
308 #ifdef TEUCHOS_DEBUG
309  TEUCHOS_ASSERT(productSpace_->isCompatible(*pv->productSpace()));
310 #endif
311  for(int k = 0; k < numBlocks_; ++k) {
312  vecs_[k].getNonconstObj()->reciprocal(*pv->getVectorBlock(k));
313  }
314  } else {
316  }
317 }
318 
319 
320 template <class Scalar>
322  const VectorBase<Scalar>& x
323  )
324 {
325  // Apply operation block-by-block if mv is also a ProductVector
327  = Teuchos::rcp_dynamic_cast<const ProductVectorBase<Scalar> >(Teuchos::rcpFromRef(x));
328  if (nonnull(pv)) {
329 #ifdef TEUCHOS_DEBUG
330  TEUCHOS_ASSERT(productSpace_->isCompatible(*pv->productSpace()));
331 #endif
332  for(int k = 0; k < numBlocks_; ++k) {
333  vecs_[k].getNonconstObj()->ele_wise_scale(*pv->getVectorBlock(k));
334  }
335  } else {
337  }
338 }
339 
340 
341 template <class Scalar>
344  const VectorBase<Scalar>& x
345  ) const
346 {
347  // Apply operation block-by-block if mv is also a ProductVector
348  typedef ScalarTraits<Scalar> ST;
350  = Teuchos::rcp_dynamic_cast<const ProductVectorBase<Scalar> >(Teuchos::rcpFromRef(x));
351  if (nonnull(pv)) {
352 #ifdef TEUCHOS_DEBUG
353  TEUCHOS_ASSERT(productSpace_->isCompatible(*pv->productSpace()));
354 #endif
355  typename ST::magnitudeType norm = ST::magnitude(ST::zero());
356  for(int k = 0; k < numBlocks_; ++k) {
357  typename ST::magnitudeType subNorm
358  = vecs_[k].getConstObj()->norm_2(*pv->getVectorBlock(k));
359  norm += subNorm*subNorm;
360  }
361  return ST::magnitude(ST::squareroot(norm));
362  } else {
364  }
365 }
366 
367 
368 template <class Scalar>
370  const RTOpPack::RTOpT<Scalar> &op,
371  const ArrayView<const Ptr<const VectorBase<Scalar> > > &vecs,
372  const ArrayView<const Ptr<VectorBase<Scalar> > > &targ_vecs,
373  const Ptr<RTOpPack::ReductTarget> &reduct_obj,
374  const Ordinal global_offset_in
375  ) const
376 {
377 
378  // 2008/02/20: rabartl: ToDo: Upgrade Teuchos::Workspace<T> to implicitly
379  // convert to Teuchos::ArrayView<T>. This will allow the calls to
380  // applyOp(...) with sub_vecs and sub_targ_vecs to work without trouble!
381  // For now, I just want to get this done. It is likely that this function
382  // is going to change in major ways soon anyway!
383 
384  //using Teuchos::Workspace;
385  using Teuchos::ptr_dynamic_cast;
386  using Teuchos::describe;
387  using Teuchos::null;
388 
389  //Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
390 
391  const Ordinal n = productSpace_->dim();
392  const int num_vecs = vecs.size();
393  const int num_targ_vecs = targ_vecs.size();
394 
395  // Validate the compatibility of the vectors!
396 #ifdef TEUCHOS_DEBUG
397  bool test_failed;
398  for(int k = 0; k < num_vecs; ++k) {
399  test_failed = !this->space()->isCompatible(*vecs[k]->space());
402  ,"DefaultProductVector::applyOp(...): Error vecs["<<k<<"]->space() = "
403  <<vecs[k]->space()->description()<<"\' is not compatible with this "
404  <<"vector space = "<<this->space()->description()<<"!"
405  );
406  }
407  for(int k = 0; k < num_targ_vecs; ++k) {
408  test_failed = !this->space()->isCompatible(*targ_vecs[k]->space());
411  ,"DefaultProductVector::applyOp(...): Error targ_vecs["<<k<<"]->space() = "
412  <<targ_vecs[k]->space()->description()<<"\' is not compatible with this "
413  <<"vector space = "<<this->space()->description()<<"!"
414  );
415  }
416 #endif
417 
418  //
419  // Dynamic cast each of the vector arguments to the ProductVectorBase interface
420  //
421  // NOTE: If the constituent vector is not a product vector, then a product
422  // vector of one component is created.
423  //
424 
425  Array<RCP<const ProductVectorBase<Scalar> > > vecs_args_store(num_vecs);
426  Array<Ptr<const ProductVectorBase<Scalar> > > vecs_args(num_vecs);
427  for(int k = 0; k < num_vecs; ++k) {
428  vecs_args_store[k] =
429  castOrCreateProductVectorBase<Scalar>(rcpFromPtr(vecs[k]));
430  vecs_args[k] = vecs_args_store[k].ptr();
431  }
432 
433  Array<RCP<ProductVectorBase<Scalar> > > targ_vecs_args_store(num_targ_vecs);
434  Array<Ptr<ProductVectorBase<Scalar> > > targ_vecs_args(num_targ_vecs);
435  for(int k = 0; k < num_targ_vecs; ++k) {
436  targ_vecs_args_store[k] =
437  castOrCreateNonconstProductVectorBase<Scalar>(rcpFromPtr(targ_vecs[k]));
438  targ_vecs_args[k] = targ_vecs_args_store[k].ptr();
439  }
440 
441  //
442  // If we get here, then we will implement the applyOpImpl(...) one vector
443  // block at a time.
444  //
445  const Ordinal dim = n;
446  Ordinal num_elements_remaining = dim;
447  const int numBlocks = productSpace_->numBlocks();
449  sub_vecs_rcps(num_vecs);
451  sub_vecs(num_vecs);
453  sub_targ_vecs_rcps(num_targ_vecs);
455  sub_targ_vecs(num_targ_vecs);
456  Ordinal g_off = 0;
457  for(int k = 0; k < numBlocks; ++k) {
458  const Ordinal dim_k = productSpace_->getBlock(k)->dim();
459  // Fill constituent vectors for block k
460  for( int i = 0; i < num_vecs; ++i ) {
461  sub_vecs_rcps[i] = vecs_args[i]->getVectorBlock(k);
462  sub_vecs[i] = sub_vecs_rcps[i].ptr();
463  }
464  // Fill constituent target vectors for block k
465  for( int j = 0; j < num_targ_vecs; ++j ) {
466  sub_targ_vecs_rcps[j] = targ_vecs_args[j]->getNonconstVectorBlock(k);
467  sub_targ_vecs[j] = sub_targ_vecs_rcps[j].ptr();
468  }
469  Thyra::applyOp<Scalar>(
470  op, sub_vecs(), sub_targ_vecs(),
471  reduct_obj,
472  global_offset_in + g_off
473  );
474  g_off += dim_k;
475  num_elements_remaining -= dim_k;
476  }
477  TEUCHOS_TEST_FOR_EXCEPT(!(num_elements_remaining==0));
478 
479 }
480 
481 
482 // protected
483 
484 
485 // Overridden protected functions from VectorBase
486 
487 
488 template <class Scalar>
490  const Range1D& rng_in, RTOpPack::ConstSubVectorView<Scalar>* sub_vec
491  ) const
492 {
493  const Range1D
494  rng = rng_in.full_range() ? Range1D(0,productSpace_->dim()-1) : rng_in;
495  int kth_vector_space = -1;
496  Ordinal kth_global_offset = 0;
497  productSpace_->getVecSpcPoss(rng.lbound(),&kth_vector_space,&kth_global_offset);
498 #ifdef TEUCHOS_DEBUG
499  TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= numBlocks_ ) );
500 #endif
501  if(
502  rng.lbound() + rng.size()
503  <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
504  )
505  {
506  // This involves only one sub-vector so just return it.
507  const_cast<const VectorBase<Scalar>*>(
508  &*vecs_[kth_vector_space].getConstObj()
509  )->acquireDetachedView( rng - kth_global_offset, sub_vec );
510  sub_vec->setGlobalOffset( sub_vec->globalOffset() + kth_global_offset );
511  }
512  else {
513  // Just let the default implementation handle this. ToDo: In the future
514  // we could manually construct an explicit sub-vector that spanned
515  // two or more constituent vectors but this would be a lot of work.
516  // However, this would require the use of temporary memory but
517  // so what.
519  }
520 }
521 
522 
523 template <class Scalar>
526  ) const
527 {
528  if( sub_vec->values().get() == NULL ) return;
529  int kth_vector_space = -1;
530  Ordinal kth_global_offset = 0;
531  productSpace_->getVecSpcPoss(sub_vec->globalOffset(),&kth_vector_space,&kth_global_offset);
532 #ifdef TEUCHOS_DEBUG
533  TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= numBlocks_ ) );
534 #endif
535  if(
536  sub_vec->globalOffset() + sub_vec->subDim()
537  <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
538  )
539  {
540  // This sub_vec was extracted from a single constituent vector
541  sub_vec->setGlobalOffset( sub_vec->globalOffset() - kth_global_offset );
542  vecs_[kth_vector_space].getConstObj()->releaseDetachedView(sub_vec);
543  }
544  else {
545  // This sub_vec was created by the default implementation!
547  }
548 }
549 
550 
551 template <class Scalar>
553  const Range1D& rng_in, RTOpPack::SubVectorView<Scalar>* sub_vec
554  )
555 {
556  const Range1D
557  rng = rng_in.full_range() ? Range1D(0,productSpace_->dim()-1) : rng_in;
558  int kth_vector_space = -1;
559  Ordinal kth_global_offset = 0;
560  productSpace_->getVecSpcPoss(rng.lbound(),&kth_vector_space,&kth_global_offset);
561 #ifdef TEUCHOS_DEBUG
562  TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= numBlocks_ ) );
563 #endif
564  if(
565  rng.lbound() + rng.size()
566  <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
567  )
568  {
569  // This involves only one sub-vector so just return it.
570  vecs_[kth_vector_space].getConstObj()->acquireDetachedView(
571  rng - kth_global_offset, sub_vec
572  );
573  sub_vec->setGlobalOffset( sub_vec->globalOffset() + kth_global_offset );
574  }
575  else {
576  // Just let the default implementation handle this. ToDo: In the future
577  // we could manually construct an explicit sub-vector that spanned
578  // two or more constituent vectors but this would be a lot of work.
579  // However, this would require the use of temporary memory but
580  // so what.
582  }
583 }
584 
585 
586 template <class Scalar>
589  )
590 {
591  if( sub_vec->values().get() == NULL ) return;
592  int kth_vector_space = -1;
593  Ordinal kth_global_offset = 0;
594  productSpace_->getVecSpcPoss(sub_vec->globalOffset(),&kth_vector_space,&kth_global_offset);
595 #ifdef TEUCHOS_DEBUG
596  TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= numBlocks_ ) );
597 #endif
598  if(
599  sub_vec->globalOffset() + sub_vec->subDim()
600  <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
601  )
602  {
603  // This sub_vec was extracted from a single constituent vector
604  sub_vec->setGlobalOffset( sub_vec->globalOffset() - kth_global_offset );
605  vecs_[kth_vector_space].getNonconstObj()->commitDetachedView(sub_vec);
606  }
607  else {
608  // This sub_vec was created by the default implementation!
610  }
611 }
612 
613 
614 template <class Scalar>
617  )
618 {
619  int kth_vector_space = -1;
620  Ordinal kth_global_offset = 0;
621  productSpace_->getVecSpcPoss(sub_vec.globalOffset(),&kth_vector_space,&kth_global_offset);
622 #ifdef TEUCHOS_DEBUG
623  TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= numBlocks_ ) );
624 #endif
625  if(
626  sub_vec.globalOffset() + sub_vec.subDim()
627  <= kth_global_offset + vecs_[kth_vector_space].getConstObj()->space()->dim()
628  )
629  {
630  // This sub-vector fits into a single constituent vector
631  RTOpPack::SparseSubVectorT<Scalar> sub_vec_g = sub_vec;
632  sub_vec_g.setGlobalOffset( sub_vec_g.globalOffset() - kth_global_offset );
633  vecs_[kth_vector_space].getNonconstObj()->setSubVector(sub_vec_g);
634  }
635  else {
636  // Let the default implementation take care of this. ToDo: In the future
637  // it would be possible to manually set the relevant constituent
638  // vectors with no temp memory allocations.
640  }
641 }
642 
643 
644 // Overridden protected functions from MultiVectorBase
645 
646 
647 template <class Scalar>
649 {
650  for(int k = 0; k < numBlocks_; ++k) {
651  vecs_[k].getNonconstObj()->assign(alpha);
652  }
653 }
654 
655 
656 template <class Scalar>
658  const MultiVectorBase<Scalar>& mv
659  )
660 {
661 #ifdef TEUCHOS_DEBUG
662  TEUCHOS_ASSERT_EQUALITY(mv.domain()->dim(), 1);
663 #endif
665  = Teuchos::rcp_dynamic_cast<const ProductMultiVectorBase<Scalar> >(Teuchos::rcpFromRef(mv));
666  if (nonnull(pv)) {
667 #ifdef TEUCHOS_DEBUG
668  TEUCHOS_ASSERT(productSpace_->isCompatible(*pv->productSpace()));
669 #endif
670  for(int k = 0; k < numBlocks_; ++k) {
671  vecs_[k].getNonconstObj()->assign(*pv->getMultiVectorBlock(k));
672  }
673  } else {
675  }
676 }
677 
678 
679 template <class Scalar>
681 {
682  for(int k = 0; k < numBlocks_; ++k) {
683  vecs_[k].getNonconstObj()->scale(alpha);
684  }
685 }
686 
687 
688 template <class Scalar>
690  Scalar alpha,
691  const MultiVectorBase<Scalar>& mv
692  )
693 {
694 #ifdef TEUCHOS_DEBUG
695  TEUCHOS_ASSERT_EQUALITY(mv.domain()->dim(), 1);
696 #endif
698  = Teuchos::rcp_dynamic_cast<const ProductMultiVectorBase<Scalar> >(Teuchos::rcpFromRef(mv));
699  if (nonnull(pv)) {
700 #ifdef TEUCHOS_DEBUG
701  TEUCHOS_ASSERT(productSpace_->isCompatible(*pv->productSpace()));
702 #endif
703  for(int k = 0; k < numBlocks_; ++k) {
704  vecs_[k].getNonconstObj()->update(alpha, *pv->getMultiVectorBlock(k));
705  }
706  } else {
708  }
709 }
710 
711 
712 template <class Scalar>
714  const ArrayView<const Scalar>& alpha,
715  const ArrayView<const Ptr<const MultiVectorBase<Scalar> > >& mv,
716  const Scalar& beta
717  )
718 {
719 #ifdef TEUCHOS_DEBUG
720  TEUCHOS_ASSERT_EQUALITY(alpha.size(), mv.size());
721 #endif
722 
723  // Apply operation block-by-block if each element of mv is also a ProductMultiVector
724  bool allCastsSuccessful = true;
726  for (Ordinal i = 0; i < mv.size(); ++i) {
727  pvs[i] = Teuchos::ptr_dynamic_cast<const ProductMultiVectorBase<Scalar> >(mv[i]);
728  if (pvs[i].is_null()) {
729  allCastsSuccessful = false;
730  break;
731  }
732 #ifdef TEUCHOS_DEBUG
733  TEUCHOS_ASSERT_EQUALITY(pvs[i]->domain()->dim(), 1);
734  TEUCHOS_ASSERT(productSpace_->isCompatible(*pvs[i]->productSpace()));
735 #endif
736  }
737 
738  if (allCastsSuccessful) {
739  Array<RCP<const MultiVectorBase<Scalar> > > blocks_rcp(pvs.size());
740  Array<Ptr<const MultiVectorBase<Scalar> > > blocks(pvs.size());
741  for (int k = 0; k < numBlocks_; ++k) {
742  for (Ordinal i = 0; i < pvs.size(); ++i) {
743  blocks_rcp[i] = pvs[i]->getMultiVectorBlock(k);
744  blocks[i] = blocks_rcp[i].ptr();
745  }
746  vecs_[k].getNonconstObj()->linear_combination(alpha, blocks(), beta);
747  }
748  } else {
750  }
751 }
752 
753 
754 template <class Scalar>
756  const MultiVectorBase<Scalar>& mv,
757  const ArrayView<Scalar>& prods
758  ) const
759 {
760 #ifdef TEUCHOS_DEBUG
761  TEUCHOS_ASSERT_EQUALITY(prods.size(), 1);
762  TEUCHOS_ASSERT_EQUALITY(mv.domain()->dim(), 1);
763 #endif
765  = Teuchos::rcp_dynamic_cast<const ProductMultiVectorBase<Scalar> >(Teuchos::rcpFromRef(mv));
766  if (nonnull(pv)) {
767 #ifdef TEUCHOS_DEBUG
768  TEUCHOS_ASSERT(productSpace_->isCompatible(*pv->productSpace()));
769 #endif
770  prods[0] = ScalarTraits<Scalar>::zero();
771  for(int k = 0; k < numBlocks_; ++k) {
772  Scalar prod;
773  vecs_[k].getConstObj()->dots(*pv->getMultiVectorBlock(k), Teuchos::arrayView(&prod, 1));
774  prods[0] += prod;
775  }
776  } else {
778  }
779 }
780 
781 
782 template <class Scalar>
784  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
785  ) const
786 {
787 #ifdef TEUCHOS_DEBUG
788  TEUCHOS_ASSERT_EQUALITY(norms.size(), 1);
789 #endif
790  typedef ScalarTraits<Scalar> ST;
791  norms[0] = ST::magnitude(ST::zero());
792  for(int k = 0; k < numBlocks_; ++k) {
793  norms[0] += vecs_[k].getConstObj()->norm_1();
794  }
795 }
796 
797 
798 template <class Scalar>
800  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
801  ) const
802 {
803 #ifdef TEUCHOS_DEBUG
804  TEUCHOS_ASSERT_EQUALITY(norms.size(), 1);
805 #endif
806  typedef ScalarTraits<Scalar> ST;
807  norms[0] = ST::magnitude(ST::zero());
808  for(int k = 0; k < numBlocks_; ++k) {
809  typename ST::magnitudeType subNorm
810  = vecs_[k].getConstObj()->norm_2();
811  norms[0] += subNorm*subNorm;
812  }
813  norms[0] = ST::magnitude(ST::squareroot(norms[0]));
814 }
815 
816 
817 template <class Scalar>
819  const ArrayView<typename ScalarTraits<Scalar>::magnitudeType>& norms
820  ) const
821 {
822 #ifdef TEUCHOS_DEBUG
823  TEUCHOS_ASSERT_EQUALITY(norms.size(), 1);
824 #endif
825  typedef ScalarTraits<Scalar> ST;
826  norms[0] = ST::magnitude(ST::zero());
827  for(int k = 0; k < numBlocks_; ++k) {
828  typename ST::magnitudeType subNorm = vecs_[k].getConstObj()->norm_inf();
829  if (subNorm > norms[0]) {
830  norms[0] = subNorm;
831  }
832  }
833 }
834 
835 
836 } // namespace Thyra
837 
838 
839 template<class Scalar>
841 Thyra::castOrCreateNonconstProductVectorBase(const RCP<VectorBase<Scalar> > v)
842 {
843  using Teuchos::rcp_dynamic_cast;
844  using Teuchos::tuple;
845  const RCP<ProductVectorBase<Scalar> > prod_v =
846  rcp_dynamic_cast<ProductVectorBase<Scalar> >(v);
847  if (nonnull(prod_v)) {
848  return prod_v;
849  }
850  return defaultProductVector<Scalar>(
851  productVectorSpace<Scalar>(tuple(v->space())()),
852  tuple(v)()
853  );
854 }
855 
856 
857 template<class Scalar>
859 Thyra::castOrCreateProductVectorBase(const RCP<const VectorBase<Scalar> > v)
860 {
861  using Teuchos::rcp_dynamic_cast;
862  using Teuchos::tuple;
863  const RCP<const ProductVectorBase<Scalar> > prod_v =
864  rcp_dynamic_cast<const ProductVectorBase<Scalar> >(v);
865  if (nonnull(prod_v)) {
866  return prod_v;
867  }
868  return defaultProductVector<Scalar>(
869  productVectorSpace<Scalar>(tuple(v->space())()),
870  tuple(v)()
871  );
872 }
873 
874 
875 //
876 // Explicit instant macro
877 //
878 
879 #define THYRA_DEFAULT_PRODUCT_VECTOR_INSTANT(SCALAR) \
880  \
881  template class DefaultProductVector<SCALAR >; \
882  \
883  template RCP<ProductVectorBase<SCALAR > > \
884  castOrCreateNonconstProductVectorBase(const RCP<VectorBase<SCALAR > > v); \
885  \
886  template RCP<const ProductVectorBase<SCALAR > > \
887  castOrCreateProductVectorBase(const RCP<const VectorBase<SCALAR > > v); \
888 
889 
890 
891 #endif // THYRA_DEFAULT_PRODUCT_VECTOR_DEF_HPP
virtual void norms2Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
void initialize(int *argc, char ***argv)
void setSubVector(const RTOpPack::SparseSubVectorT< Scalar > &sub_vec)
Calls setSubVectorImpl().
Base interface for product multi-vectors.
virtual void normsInfImpl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
void setSubVectorImpl(const RTOpPack::SparseSubVectorT< Scalar > &sub_vec)
void commitNonconstDetachedVectorViewImpl(RTOpPack::SubVectorView< Scalar > *sub_vec)
bool is_null(const boost::shared_ptr< T > &p)
Base interface for product vectors.
Thrown if vector spaces are incompatible.
basic_OSTab< char > OSTab
virtual void releaseDetachedVectorViewImpl(RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
RCP< const VectorBase< Scalar > > getVectorBlock(const int k) const
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)
Default implementation of assign(MV) using RTOps.
basic_FancyOStream< char > FancyOStream
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
size_type size() const
virtual void eleWiseScaleImpl(const VectorBase< Scalar > &x)
Default implementation of ele_wise_scale using RTOps.
virtual void reciprocalImpl(const VectorBase< Scalar > &x)
Default implementation of reciprocal using RTOps.
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 void absImpl(const VectorBase< Scalar > &x)
Default implementation of abs using RTOps.
void releaseDetachedVectorViewImpl(RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
virtual void absImpl(const VectorBase< Scalar > &x)
virtual void reciprocalImpl(const VectorBase< Scalar > &x)
bool full_range() const
virtual void assignMultiVecImpl(const MultiVectorBase< Scalar > &mv)
const ArrayRCP< Scalar > values() const
void setNonconstBlock(int i, const RCP< VectorBase< Scalar > > &b)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual void dotsImpl(const MultiVectorBase< Scalar > &mv, const ArrayView< Scalar > &prods) const
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
Interface for a collection of column vectors called a multi-vector.
void applyOpImpl(const RTOpPack::RTOpT< Scalar > &op, const ArrayView< const Ptr< const VectorBase< Scalar > > > &vecs, const ArrayView< const Ptr< VectorBase< Scalar > > > &targ_vecs, const Ptr< RTOpPack::ReductTarget > &reduct_obj, const Ordinal global_offset) const
DefaultProductVector()
Construct to uninitialized.
RCP< const VectorSpaceBase< Scalar > > space() const
void acquireNonconstDetachedVectorViewImpl(const Range1D &rng, RTOpPack::SubVectorView< Scalar > *sub_vec)
virtual std::string description() const
Abstract interface for finite-dimensional dense vectors.
virtual void eleWiseScaleImpl(const VectorBase< Scalar > &x)
RCP< VectorBase< Scalar > > getNonconstVectorBlock(const int k)
Ordinal globalOffset() const
Teuchos_Ordinal subDim() const
void setGlobalOffset(Ordinal globalOffset_in)
Ordinal lbound() const
void setGlobalOffset(Teuchos_Ordinal globalOffset_in)
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)
RCP< MultiVectorBase< Scalar > > getNonconstMultiVectorBlock(const int k)
Ordinal size() const
TypeTo as(const TypeFrom &t)
virtual Teuchos::ScalarTraits< Scalar >::magnitudeType norm2WeightedImpl(const VectorBase< Scalar > &x) const
Default implementation of norm_2 (weighted) using RTOps.
virtual void acquireDetachedVectorViewImpl(const Range1D &rng, RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
Teuchos_Ordinal globalOffset() const
#define TEUCHOS_ASSERT(assertion_test)
virtual void acquireNonconstDetachedVectorViewImpl(const Range1D &rng, RTOpPack::SubVectorView< Scalar > *sub_vec)
void acquireDetachedVectorViewImpl(const Range1D &rng, RTOpPack::ConstSubVectorView< Scalar > *sub_vec) const
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
RCP< const ProductVectorSpaceBase< Scalar > > productSpace() const
void setBlock(int i, const RCP< const VectorBase< Scalar > > &b)
T * get() const
virtual Teuchos::ScalarTraits< Scalar >::magnitudeType norm2WeightedImpl(const VectorBase< Scalar > &x) const
void initialize(const RCP< const DefaultProductVectorSpace< Scalar > > &productSpace)
Initialize.
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)
RCP< const MultiVectorBase< Scalar > > getMultiVectorBlock(const int k) const
const ArrayRCP< const Scalar > values() const
virtual void updateImpl(Scalar alpha, const MultiVectorBase< Scalar > &mv)
Default implementation of update using RTOps.
Teuchos::Range1D Range1D
virtual void norms1Impl(const ArrayView< typename ScalarTraits< Scalar >::magnitudeType > &norms) const
virtual void commitNonconstDetachedVectorViewImpl(RTOpPack::SubVectorView< Scalar > *sub_vec)