103 assertBlockFillIsActive(
true);
110 if (nonnull(productRange_)) {
111 numRowBlocks_ = productRange_->numBlocks();
112 numColBlocks_ = productDomain_->numBlocks();
115 numRowBlocks_ = rangeBlocks_.size();
116 numColBlocks_ = domainBlocks_.size();
156 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"endBlockFill is used!");
170 blockFillIsActive_ =
false;
175template<
class SC,
class LO,
class GO,
class NO>
178 productRange_ = Teuchos::null;
179 productDomain_ = Teuchos::null;
183 Ops_stack_.resize(0);
184 rangeBlocks_.resize(0);
185 domainBlocks_.resize(0);
186 blockFillIsActive_ =
false;
193template<
class SC,
class LO,
class GO,
class NO>
194Teuchos::RCP<const ProductVectorSpaceBase<SC> >
197 return productRange_;
201template<
class SC,
class LO,
class GO,
class NO>
202Teuchos::RCP<const ProductVectorSpaceBase<SC> >
205 return productDomain_;
209template<
class SC,
class LO,
class GO,
class NO>
211 const int i,
const int j
214 assertBlockFillIsActive(
false);
215 assertBlockRowCol(i,j);
220template<
class SC,
class LO,
class GO,
class NO>
222 const int i,
const int j
228 assertBlockFillIsActive(
false);
229 assertBlockRowCol(i,j);
230 return Ops_[numRowBlocks_*j+i].isConst();
234template<
class SC,
class LO,
class GO,
class NO>
235Teuchos::RCP<LinearOpBase<SC> >
241 assertBlockFillIsActive(
false);
242 assertBlockRowCol(i,j);
243 return Ops_[numRowBlocks_*j+i].getNonconstObj();
247template<
class SC,
class LO,
class GO,
class NO>
248Teuchos::RCP<const LinearOpBase<SC> >
254 assertBlockFillIsActive(
false);
255 assertBlockRowCol(i,j);
256 return Ops_[numRowBlocks_*j+i];
263template<
class SC,
class LO,
class GO,
class NO>
264Teuchos::RCP< const VectorSpaceBase<SC> >
265PreconditionerOperator<SC, LO, GO, NO>::range()
const
267 return productRange_;
271template<
class SC,
class LO,
class GO,
class NO>
272Teuchos::RCP< const VectorSpaceBase<SC> >
273PreconditionerOperator<SC, LO, GO, NO>::domain()
const
275 return productDomain_;
279template<
class SC,
class LO,
class GO,
class NO>
280Teuchos::RCP<const LinearOpBase<SC> >
281PreconditionerOperator<SC, LO, GO, NO>::clone()
const
283 return Teuchos::null;
290template<
class SC,
class LO,
class GO,
class NO>
291std::string PreconditionerOperator<SC, LO, GO, NO>::description()
const
293 assertBlockFillIsActive(
false);
294 std::ostringstream oss;
296 << Teuchos::Describable::description() <<
"{"
297 <<
"numRowBlocks="<<numRowBlocks_
298 <<
",numColBlocks="<<numColBlocks_
304template<
class SC,
class LO,
class GO,
class NO>
305void PreconditionerOperator<SC, LO, GO, NO>::describe(
306 Teuchos::FancyOStream &out_arg
307 ,
const Teuchos::EVerbosityLevel verbLevel
310 using Teuchos::rcpFromRef;
311 using Teuchos::FancyOStream;
312 using Teuchos::OSTab;
313 assertBlockFillIsActive(
false);
314 RCP<FancyOStream> out = rcpFromRef(out_arg);
317 case Teuchos::VERB_DEFAULT:
318 case Teuchos::VERB_LOW:
319 *out << this->description() << std::endl;
321 case Teuchos::VERB_MEDIUM:
322 case Teuchos::VERB_HIGH:
323 case Teuchos::VERB_EXTREME:
326 << Teuchos::Describable::description() <<
"{"
327 <<
"rangeDim=" << this->range()->dim()
328 <<
",domainDim=" << this->domain()->dim()
329 <<
",numRowBlocks=" << numRowBlocks_
330 <<
",numColBlocks=" << numColBlocks_
334 <<
"Constituent LinearOpBase objects for M = [ Op[0,0] ..."
335 <<
" ; ... ; ... Op[numRowBlocks-1,numColBlocks-1] ]:\n";
337 for(
int i = 0; i < numRowBlocks_; ++i ) {
338 for(
int j = 0; j < numColBlocks_; ++j ) {
339 *out <<
"Op["<<i<<
","<<j<<
"] = ";
340 RCP<const LinearOpBase<SC> >
341 block_i_j = getBlock(i,j);
343 *out << Teuchos::describe(*getBlock(i,j),verbLevel);
351 TEUCHOS_TEST_FOR_EXCEPT(
true);
362template<
class SC,
class LO,
class GO,
class NO>
365 bool supported =
true;
366 for(
int i = 0; i < numRowBlocks_; ++i ) {
367 for(
int j = 0; j < numColBlocks_; ++j ) {
368 RCP<const LinearOpBase<SC> >
370 if( block_i_j.get() && !Thyra::opSupported(*block_i_j,M_trans) )
380template<
class SC,
class LO,
class GO,
class NO>
381void PreconditionerOperator<SC, LO, GO, NO>::resetStorage(
382 const int numRowBlocks,
const int numColBlocks
385 numRowBlocks_ = numRowBlocks;
386 numColBlocks_ = numColBlocks;
387 Ops_.resize(numRowBlocks_*numColBlocks_);
388 if (is_null(productRange_)) {
389 rangeBlocks_.resize(numRowBlocks);
390 domainBlocks_.resize(numColBlocks);
392 blockFillIsActive_ =
true;
396template<
class SC,
class LO,
class GO,
class NO>
397void PreconditionerOperator<SC, LO, GO, NO>::assertBlockFillIsActive(
402 TEUCHOS_TEST_FOR_EXCEPT(!(blockFillIsActive_==wantedValue));
409template<
class SC,
class LO,
class GO,
class NO>
410void PreconditionerOperator<SC, LO, GO, NO>::assertBlockRowCol(
411 const int i,
const int j
415 TEUCHOS_TEST_FOR_EXCEPTION(
416 !( 0 <= i ), std::logic_error
417 ,
"Error, i="<<i<<
" is invalid!"
419 TEUCHOS_TEST_FOR_EXCEPTION(
420 !( 0 <= j ), std::logic_error
421 ,
"Error, j="<<j<<
" is invalid!"
426 TEUCHOS_TEST_FOR_EXCEPTION(
427 !( 0 <= i && i < numRowBlocks_ ), std::logic_error
428 ,
"Error, i="<<i<<
" does not fall in the range [0,"<<numRowBlocks_-1<<
"]!"
430 TEUCHOS_TEST_FOR_EXCEPTION(
431 !( 0 <= j && j < numColBlocks_ ), std::logic_error
432 ,
"Error, j="<<j<<
" does not fall in the range [0,"<<numColBlocks_-1<<
"]!"
442template<
class SC,
class LO,
class GO,
class NO>
443void PreconditionerOperator<SC, LO, GO, NO>::setBlockSpaces(
444 const int i,
const int j,
const LinearOpBase<SC> &block
447 using Teuchos::toString;
448 assertBlockFillIsActive(
true);
449 assertBlockRowCol(i,j);
453 if( i < numRowBlocks_ && j < numColBlocks_ ) {
455 RCP<const VectorSpaceBase<SC> >
458 ? productRange_->getBlock(i)
463 ? productDomain_->getBlock(j)
487 for(
int k = numRowBlocks_; k <= i; ++k )
488 rangeBlocks_.push_back(Teuchos::null);
489 for(
int k = numColBlocks_; k <= j; ++k )
490 domainBlocks_.push_back(Teuchos::null);
493 if(!productRange_.get()) {
494 if(!rangeBlocks_[i].get())
495 rangeBlocks_[i] = block.range().assert_not_null();
496 if(!domainBlocks_[j].get()) {
497 domainBlocks_[j] = block.domain().assert_not_null();
504 numRowBlocks_ = rangeBlocks_.size();
505 numColBlocks_ = domainBlocks_.size();
511template<
class SC,
class LO,
class GO,
class NO>
512template<
class LinearOpType>
513void PreconditionerOperator<SC, LO, GO, NO>::setBlockImpl(
514 const int i,
const int j,
515 const RCP<LinearOpType> &block
518 setBlockSpaces(i, j, *block);
522 Ops_[numRowBlocks_*j+i] = block;
527 bool foundBlock =
false;
528 for(
unsigned int k = 0; k < Ops_stack_.size(); ++k ) {
529 BlockEntry<SC> &block_i_j = Ops_stack_[k];
530 if( block_i_j.i == i && block_i_j.j == j ) {
531 block_i_j.block = block;
537 Ops_stack_.push_back(BlockEntry<SC>(i,j,block));
542template<
class SC,
class LO,
class GO,
class NO>
543void PreconditionerOperator<SC, LO, GO, NO>::adjustBlockSpaces()
547 TEUCHOS_ASSERT_INEQUALITY(Ops_.size(), !=, 0);
562 for (
int i = 0; i < numRowBlocks_; ++i) {
563 for (
int j = 0; j < numColBlocks_; ++j) {
564 const RCP<const LinearOpBase<SC> >
565 op_i_j = Ops_[numRowBlocks_*j+i];
568 const RCP<const VectorSpaceBase<SC> > range_i_j = op_i_j->range();
569 if (is_null(productVectorSpaceBase<SC>(range_i_j,
false))) {
570 rangeBlocks_[i] = range_i_j;
577 for (
int j = 0; j < numColBlocks_; ++j) {
578 for (
int i = 0; i < numRowBlocks_; ++i) {
579 const RCP<const LinearOpBase<SC> >
580 op_i_j = Ops_[numRowBlocks_*j+i];
583 const RCP<const VectorSpaceBase<SC> >
584 domain_i_j = op_i_j->domain();
585 if (is_null(productVectorSpaceBase<SC>(domain_i_j,
false))) {
586 domainBlocks_[j] = domain_i_j;