101 assertBlockFillIsActive(
true);
108 if (nonnull(productRange_)) {
109 numRowBlocks_ = productRange_->numBlocks();
110 numColBlocks_ = productDomain_->numBlocks();
113 numRowBlocks_ = rangeBlocks_.size();
114 numColBlocks_ = domainBlocks_.size();
154 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"endBlockFill is used!");
168 blockFillIsActive_ =
false;
173template<
class SC,
class LO,
class GO,
class NO>
176 productRange_ = Teuchos::null;
177 productDomain_ = Teuchos::null;
181 Ops_stack_.resize(0);
182 rangeBlocks_.resize(0);
183 domainBlocks_.resize(0);
184 blockFillIsActive_ =
false;
191template<
class SC,
class LO,
class GO,
class NO>
192Teuchos::RCP<const Thyra::ProductVectorSpaceBase<SC> >
195 return productRange_;
199template<
class SC,
class LO,
class GO,
class NO>
200Teuchos::RCP<const Thyra::ProductVectorSpaceBase<SC> >
203 return productDomain_;
207template<
class SC,
class LO,
class GO,
class NO>
209 const int i,
const int j
212 assertBlockFillIsActive(
false);
213 assertBlockRowCol(i,j);
218template<
class SC,
class LO,
class GO,
class NO>
220 const int i,
const int j
226 assertBlockFillIsActive(
false);
227 assertBlockRowCol(i,j);
228 return Ops_[numRowBlocks_*j+i].isConst();
232template<
class SC,
class LO,
class GO,
class NO>
233Teuchos::RCP<Thyra::LinearOpBase<SC> >
239 assertBlockFillIsActive(
false);
240 assertBlockRowCol(i,j);
241 return Ops_[numRowBlocks_*j+i].getNonconstObj();
245template<
class SC,
class LO,
class GO,
class NO>
246Teuchos::RCP<const Thyra::LinearOpBase<SC> >
252 assertBlockFillIsActive(
false);
253 assertBlockRowCol(i,j);
254 return Ops_[numRowBlocks_*j+i];
261template<
class SC,
class LO,
class GO,
class NO>
262Teuchos::RCP< const Thyra::VectorSpaceBase<SC> >
263PreconditionerOperator<SC, LO, GO, NO>::range()
const
265 return productRange_;
269template<
class SC,
class LO,
class GO,
class NO>
270Teuchos::RCP< const Thyra::VectorSpaceBase<SC> >
271PreconditionerOperator<SC, LO, GO, NO>::domain()
const
273 return productDomain_;
277template<
class SC,
class LO,
class GO,
class NO>
278Teuchos::RCP<const Thyra::LinearOpBase<SC> >
279PreconditionerOperator<SC, LO, GO, NO>::clone()
const
281 return Teuchos::null;
288template<
class SC,
class LO,
class GO,
class NO>
289std::string PreconditionerOperator<SC, LO, GO, NO>::description()
const
291 assertBlockFillIsActive(
false);
292 std::ostringstream oss;
294 << Teuchos::Describable::description() <<
"{"
295 <<
"numRowBlocks="<<numRowBlocks_
296 <<
",numColBlocks="<<numColBlocks_
302template<
class SC,
class LO,
class GO,
class NO>
303void PreconditionerOperator<SC, LO, GO, NO>::describe(
304 Teuchos::FancyOStream &out_arg
305 ,
const Teuchos::EVerbosityLevel verbLevel
308 using Teuchos::rcpFromRef;
309 using Teuchos::FancyOStream;
310 using Teuchos::OSTab;
311 assertBlockFillIsActive(
false);
312 Teuchos::RCP<FancyOStream> out = rcpFromRef(out_arg);
315 case Teuchos::VERB_DEFAULT:
316 case Teuchos::VERB_LOW:
317 *out << this->description() << std::endl;
319 case Teuchos::VERB_MEDIUM:
320 case Teuchos::VERB_HIGH:
321 case Teuchos::VERB_EXTREME:
324 << Teuchos::Describable::description() <<
"{"
325 <<
"rangeDim=" << this->range()->dim()
326 <<
",domainDim=" << this->domain()->dim()
327 <<
",numRowBlocks=" << numRowBlocks_
328 <<
",numColBlocks=" << numColBlocks_
332 <<
"Constituent LinearOpBase objects for M = [ Op[0,0] ..."
333 <<
" ; ... ; ... Op[numRowBlocks-1,numColBlocks-1] ]:\n";
335 for(
int i = 0; i < numRowBlocks_; ++i ) {
336 for(
int j = 0; j < numColBlocks_; ++j ) {
337 *out <<
"Op["<<i<<
","<<j<<
"] = ";
338 Teuchos::RCP<const Thyra::LinearOpBase<SC> >
339 block_i_j = getBlock(i,j);
341 *out << Teuchos::describe(*getBlock(i,j),verbLevel);
349 TEUCHOS_TEST_FOR_EXCEPT(
true);
360template<
class SC,
class LO,
class GO,
class NO>
363 bool supported =
true;
364 for(
int i = 0; i < numRowBlocks_; ++i ) {
365 for(
int j = 0; j < numColBlocks_; ++j ) {
366 Teuchos::RCP<const Thyra::LinearOpBase<SC> >
368 if( block_i_j.get() && !Thyra::opSupported(*block_i_j,M_trans) )
378template<
class SC,
class LO,
class GO,
class NO>
379void PreconditionerOperator<SC, LO, GO, NO>::resetStorage(
380 const int numRowBlocks,
const int numColBlocks
383 numRowBlocks_ = numRowBlocks;
384 numColBlocks_ = numColBlocks;
385 Ops_.resize(numRowBlocks_*numColBlocks_);
386 if (is_null(productRange_)) {
387 rangeBlocks_.resize(numRowBlocks);
388 domainBlocks_.resize(numColBlocks);
390 blockFillIsActive_ =
true;
394template<
class SC,
class LO,
class GO,
class NO>
395void PreconditionerOperator<SC, LO, GO, NO>::assertBlockFillIsActive(
400 TEUCHOS_TEST_FOR_EXCEPT(!(blockFillIsActive_==wantedValue));
407template<
class SC,
class LO,
class GO,
class NO>
408void PreconditionerOperator<SC, LO, GO, NO>::assertBlockRowCol(
409 const int i,
const int j
413 TEUCHOS_TEST_FOR_EXCEPTION(
414 !( 0 <= i ), std::logic_error
415 ,
"Error, i="<<i<<
" is invalid!"
417 TEUCHOS_TEST_FOR_EXCEPTION(
418 !( 0 <= j ), std::logic_error
419 ,
"Error, j="<<j<<
" is invalid!"
424 TEUCHOS_TEST_FOR_EXCEPTION(
425 !( 0 <= i && i < numRowBlocks_ ), std::logic_error
426 ,
"Error, i="<<i<<
" does not fall in the range [0,"<<numRowBlocks_-1<<
"]!"
428 TEUCHOS_TEST_FOR_EXCEPTION(
429 !( 0 <= j && j < numColBlocks_ ), std::logic_error
430 ,
"Error, j="<<j<<
" does not fall in the range [0,"<<numColBlocks_-1<<
"]!"
440template<
class SC,
class LO,
class GO,
class NO>
441void PreconditionerOperator<SC, LO, GO, NO>::setBlockSpaces(
442 const int i,
const int j,
const Thyra::LinearOpBase<SC> &block
445 using Teuchos::toString;
446 assertBlockFillIsActive(
true);
447 assertBlockRowCol(i,j);
451 if( i < numRowBlocks_ && j < numColBlocks_ ) {
453 Teuchos::RCP<const Thyra::VectorSpaceBase<SC> >
456 ? productRange_->getBlock(i)
461 ? productDomain_->getBlock(j)
485 for(
int k = numRowBlocks_; k <= i; ++k )
486 rangeBlocks_.push_back(Teuchos::null);
487 for(
int k = numColBlocks_; k <= j; ++k )
488 domainBlocks_.push_back(Teuchos::null);
491 if(!productRange_.get()) {
492 if(!rangeBlocks_[i].get())
493 rangeBlocks_[i] = block.range().assert_not_null();
494 if(!domainBlocks_[j].get()) {
495 domainBlocks_[j] = block.domain().assert_not_null();
502 numRowBlocks_ = rangeBlocks_.size();
503 numColBlocks_ = domainBlocks_.size();
509template<
class SC,
class LO,
class GO,
class NO>
510template<
class LinearOpType>
511void PreconditionerOperator<SC, LO, GO, NO>::setBlockImpl(
512 const int i,
const int j,
513 const Teuchos::RCP<LinearOpType> &block
516 setBlockSpaces(i, j, *block);
520 Ops_[numRowBlocks_*j+i] = block;
525 bool foundBlock =
false;
526 for(
unsigned int k = 0; k < Ops_stack_.size(); ++k ) {
527 BlockEntry<SC> &block_i_j = Ops_stack_[k];
528 if( block_i_j.i == i && block_i_j.j == j ) {
529 block_i_j.block = block;
535 Ops_stack_.push_back(BlockEntry<SC>(i,j,block));
540template<
class SC,
class LO,
class GO,
class NO>
541void PreconditionerOperator<SC, LO, GO, NO>::adjustBlockSpaces()
545 TEUCHOS_ASSERT_INEQUALITY(Ops_.size(), !=, 0);
560 for (
int i = 0; i < numRowBlocks_; ++i) {
561 for (
int j = 0; j < numColBlocks_; ++j) {
562 const Teuchos::RCP<const Thyra::LinearOpBase<SC> >
563 op_i_j = Ops_[numRowBlocks_*j+i];
566 const Teuchos::RCP<const Thyra::VectorSpaceBase<SC> > range_i_j = op_i_j->range();
567 if (is_null(Thyra::productVectorSpaceBase<SC>(range_i_j,
false))) {
568 rangeBlocks_[i] = range_i_j;
575 for (
int j = 0; j < numColBlocks_; ++j) {
576 for (
int i = 0; i < numRowBlocks_; ++i) {
577 const Teuchos::RCP<const Thyra::LinearOpBase<SC> >
578 op_i_j = Ops_[numRowBlocks_*j+i];
581 const Teuchos::RCP<const Thyra::VectorSpaceBase<SC> >
582 domain_i_j = op_i_j->domain();
583 if (is_null(Thyra::productVectorSpaceBase<SC>(domain_i_j,
false))) {
584 domainBlocks_[j] = domain_i_j;