15#include "Teko_BlockedReordering.hpp"
18#include "Teuchos_VerboseObject.hpp"
19#include "Teuchos_RCP.hpp"
20#include "Teuchos_StrUtils.hpp"
22#include "Thyra_DefaultProductMultiVector.hpp"
23#include "Thyra_DefaultProductVectorSpace.hpp"
28using Teuchos::rcp_dynamic_cast;
33 TEUCHOS_ASSERT(blockIndex < (
int)
children_.size());
53 TEUCHOS_ASSERT(blockIndex < (
int)
children_.size());
59 TEUCHOS_ASSERT(blockIndex < (
int)
children_.size());
61 if (
children_[blockIndex] == Teuchos::null)
68 TEUCHOS_ASSERT(blockIndex < (
int)
children_.size());
77 for (
unsigned int i = 0; i <
children_.size(); i++) {
81 ss <<
" " <<
children_[i]->toString() <<
" ";
90 for (
unsigned int i = 0; i <
children_.size(); i++) {
93 int subMax =
children_[i]->LargestIndex();
94 max = max > subMax ? max : subMax;
103 const Teuchos::RCP<
const Thyra::BlockedLinearOpBase<double> > &blkOp) {
109 const Teuchos::RCP<
const Thyra::BlockedLinearOpBase<double> > &blkOp) {
110 typedef RCP<const BlockReorderManager> BRMptr;
115 if (rowSz == 0 && colSz == 0) {
121 Teko::LinearOp linOp = blkOp->getBlock(rowLeaf.
GetIndex(), colLeaf.
GetIndex());
124 if (linOp == Teuchos::null) {
125 linOp = Thyra::zero(blkOp->productRange()->getBlock(rowLeaf.
GetIndex()),
126 blkOp->productDomain()->getBlock(colLeaf.
GetIndex()));
130 }
else if (rowSz == 0) {
131 Teko::BlockedLinearOp reBlkOp = Teko::createBlockedOp();
134 reBlkOp->beginBlockFill(1, colSz);
137 for (
int col = 0; col < colSz; col++) {
138 BRMptr colPtr = colMgr.
GetBlock(col);
144 reBlkOp->endBlockFill();
147 }
else if (colSz == 0) {
148 Teko::BlockedLinearOp reBlkOp = Teko::createBlockedOp();
151 reBlkOp->beginBlockFill(rowSz, 1);
154 for (
int row = 0; row < rowSz; row++) {
155 BRMptr rowPtr = rowMgr.
GetBlock(row);
161 reBlkOp->endBlockFill();
165 Teko::BlockedLinearOp reBlkOp = Teko::createBlockedOp();
168 TEUCHOS_ASSERT(rowSz > 0);
169 TEUCHOS_ASSERT(colSz > 0);
172 reBlkOp->beginBlockFill(rowSz, colSz);
174 for (
int row = 0; row < rowSz; row++) {
175 BRMptr rowPtr = rowMgr.
GetBlock(row);
177 for (
int col = 0; col < colSz; col++) {
178 BRMptr colPtr = colMgr.
GetBlock(col);
185 reBlkOp->endBlockFill();
214 const Teuchos::RCP<
const Thyra::ProductVectorSpaceBase<double> > &blkSpc) {
215 typedef RCP<const BlockReorderManager> BRMptr;
224 return blkSpc->getBlock(leaf.
GetIndex());
226 Array<RCP<const Thyra::VectorSpaceBase<double> > > vecSpaces;
229 for (
int i = 0; i < sz; i++) {
232 const RCP<const Thyra::VectorSpaceBase<double> > lvs =
235 vecSpaces.push_back(lvs);
239 const RCP<const Thyra::DefaultProductVectorSpace<double> > vs =
240 Thyra::productVectorSpace<double>(vecSpaces);
253 const Teuchos::RCP<Thyra::ProductMultiVectorBase<double> > &blkVec) {
254 typedef RCP<const BlockReorderManager> BRMptr;
263 return blkVec->getNonconstMultiVectorBlock(leaf.
GetIndex());
265 Array<RCP<Thyra::MultiVectorBase<double> > > multiVecs;
266 Array<RCP<const Thyra::VectorSpaceBase<double> > > vecSpaces;
269 for (
int i = 0; i < sz; i++) {
273 const RCP<const Thyra::VectorSpaceBase<double> > lvs = lmv->range();
275 multiVecs.push_back(lmv);
276 vecSpaces.push_back(lvs);
280 const RCP<const Thyra::DefaultProductVectorSpace<double> > vs =
281 Thyra::productVectorSpace<double>(vecSpaces);
284 return Thyra::defaultProductMultiVector<double>(vs, multiVecs);
294 const Teuchos::RCP<
const Thyra::ProductMultiVectorBase<double> > &blkVec) {
295 typedef RCP<const BlockReorderManager> BRMptr;
304 return blkVec->getMultiVectorBlock(leaf.
GetIndex());
306 Array<RCP<const Thyra::MultiVectorBase<double> > > multiVecs;
307 Array<RCP<const Thyra::VectorSpaceBase<double> > > vecSpaces;
310 for (
int i = 0; i < sz; i++) {
313 const RCP<const Thyra::MultiVectorBase<double> > lmv =
315 const RCP<const Thyra::VectorSpaceBase<double> > lvs = lmv->range();
317 multiVecs.push_back(lmv);
318 vecSpaces.push_back(lvs);
322 const RCP<const Thyra::DefaultProductVectorSpace<double> > vs =
323 Thyra::productVectorSpace<double>(vecSpaces);
326 return Thyra::defaultProductMultiVector<double>(vs, multiVecs);
334 const RCP<Thyra::MultiVectorBase<double> > &blkVec,
335 Array<RCP<Thyra::MultiVectorBase<double> > > &multivecs,
336 Array<RCP<
const Thyra::VectorSpaceBase<double> > > &vecspaces) {
345 multivecs[index] = blkVec;
346 vecspaces[index] = blkVec->range();
348 const RCP<Thyra::ProductMultiVectorBase<double> > prodMV =
349 rcp_dynamic_cast<Thyra::ProductMultiVectorBase<double> >(blkVec);
352 for (
int i = 0; i < sz; i++) {
353 const RCP<Thyra::MultiVectorBase<double> > mv = prodMV->getNonconstMultiVectorBlock(i);
354 buildNonconstFlatMultiVector(*mgr.
GetBlock(i), mv, multivecs, vecspaces);
363 const RCP<
const Thyra::MultiVectorBase<double> > &blkVec,
364 Array<RCP<
const Thyra::MultiVectorBase<double> > > &multivecs,
365 Array<RCP<
const Thyra::VectorSpaceBase<double> > > &vecspaces) {
366 int sz = mgr.GetNumBlocks();
374 multivecs[index] = blkVec;
375 vecspaces[index] = blkVec->range();
377 const RCP<const Thyra::ProductMultiVectorBase<double> > prodMV =
378 rcp_dynamic_cast<const Thyra::ProductMultiVectorBase<double> >(blkVec);
381 for (
int i = 0; i < sz; i++) {
382 RCP<const Thyra::MultiVectorBase<double> > mv = prodMV->getMultiVectorBlock(i);
383 buildFlatMultiVector(*mgr.GetBlock(i), mv, multivecs, vecspaces);
394 const Teuchos::RCP<Thyra::ProductMultiVectorBase<double> > &blkVec) {
397 Array<RCP<Thyra::MultiVectorBase<double> > > multivecs(numBlocks);
398 Array<RCP<const Thyra::VectorSpaceBase<double> > > vecspaces(numBlocks);
401 buildNonconstFlatMultiVector(mgr, blkVec, multivecs, vecspaces);
404 const RCP<Thyra::DefaultProductVectorSpace<double> > vs =
405 Thyra::productVectorSpace<double>(vecspaces);
408 return Thyra::defaultProductMultiVector<double>(vs, multivecs);
417 const Teuchos::RCP<
const Thyra::ProductMultiVectorBase<double> > &blkVec) {
420 Array<RCP<const Thyra::MultiVectorBase<double> > > multivecs(numBlocks);
421 Array<RCP<const Thyra::VectorSpaceBase<double> > > vecspaces(numBlocks);
427 const RCP<const Thyra::DefaultProductVectorSpace<double> > vs =
428 Thyra::productVectorSpace<double>(vecspaces);
431 return Thyra::defaultProductMultiVector<double>(vs, multivecs);
438 const RCP<
const Thyra::VectorSpaceBase<double> > &blkSpc,
439 Array<RCP<
const Thyra::VectorSpaceBase<double> > > &vecspaces) {
448 vecspaces[index] = blkSpc;
450 const RCP<const Thyra::ProductVectorSpaceBase<double> > prodSpc =
451 rcp_dynamic_cast<const Thyra::ProductVectorSpaceBase<double> >(blkSpc);
454 for (
int i = 0; i < sz; i++) {
455 RCP<const Thyra::VectorSpaceBase<double> > space = prodSpc->getBlock(i);
456 buildFlatVectorSpace(*mgr.
GetBlock(i), space, vecspaces);
463Teuchos::RCP<const Thyra::VectorSpaceBase<double> > buildFlatVectorSpace(
465 const Teuchos::RCP<
const Thyra::VectorSpaceBase<double> > &blkSpc) {
466 int numBlocks = mgr.LargestIndex() + 1;
468 Array<RCP<const Thyra::VectorSpaceBase<double> > > vecspaces(numBlocks);
471 buildFlatVectorSpace(mgr, blkSpc, vecspaces);
474 return Thyra::productVectorSpace<double>(vecspaces);
484static void tokenize(std::string srcInput, std::string whitespace, std::string prefer,
485 std::vector<std::string> &tokens) {
486 std::string input = srcInput;
487 std::vector<std::string> wsTokens;
488 std::size_t endPos = input.length() - 1;
489 while (endPos < input.length()) {
490 std::size_t next = input.find_first_of(whitespace);
494 if (next != std::string::npos) {
495 s = input.substr(0, next);
498 input = input.substr(next + 1, endPos);
504 endPos = input.length() - 1;
507 if (s ==
"")
continue;
508 wsTokens.push_back(s);
511 for (
unsigned int i = 0; i < wsTokens.size(); i++) {
515 endPos = input.length() - 1;
516 while (endPos < input.length()) {
517 std::size_t next = input.find_first_of(prefer);
519 std::string s = input;
520 if (next > 0 && next < input.length()) {
522 s = input.substr(0, next);
524 input = input.substr(next, endPos);
525 }
else if (next == 0) {
527 s = input.substr(0, next + 1);
529 input = input.substr(next + 1, endPos);
534 endPos = input.length() - 1;
544static std::vector<std::string>::const_iterator buildSubBlock(
545 std::vector<std::string>::const_iterator begin, std::vector<std::string>::const_iterator end,
546 std::vector<std::string> &subBlock) {
547 std::stack<std::string> matched;
548 std::vector<std::string>::const_iterator itr;
549 for (itr = begin; itr != end; ++itr) {
550 subBlock.push_back(*itr);
555 else if (*itr ==
"]")
559 if (matched.empty())
return itr;
562 TEUCHOS_ASSERT(matched.empty());
568static RCP<BlockReorderManager> blockedReorderFromTokens(
const std::vector<std::string> &tokens) {
570 if (tokens.size() == 1)
571 return rcp(
new Teko::BlockReorderLeaf(Teuchos::StrUtils::atoi(tokens[0])));
574 TEUCHOS_ASSERT(*(tokens.begin()) ==
"[")
575 TEUCHOS_ASSERT(*(tokens.end() - 1) ==
"]");
578 std::vector<std::
string>::const_iterator itr = tokens.begin() + 1;
579 while (itr != tokens.end() - 1) {
581 std::vector<std::string> subBlock;
582 itr = buildSubBlock(itr, tokens.end() - 1, subBlock);
585 vecRMgr.push_back(blockedReorderFromTokens(subBlock));
592 RCP<Teko::BlockReorderManager> rMgr = rcp(
new Teko::BlockReorderManager(vecRMgr.size()));
593 for (
unsigned int i = 0; i < vecRMgr.size(); i++) rMgr->SetBlock(i, vecRMgr[i]);
613 std::vector<std::string> tokens;
618 tokenize(reorder,
" \t\n",
"[]", tokens);
621 Teuchos::RCP<BlockReorderManager> mgr = blockedReorderFromTokens(tokens);
int GetIndex() const
Get the the index that is stored in this block.
Class that describes how a flat blocked operator should be reordered.
virtual std::string toString() const
For sanities sake, print a readable string.
Teuchos::RCP< Thyra::MultiVectorBase< double > > buildReorderedMultiVector(const BlockReorderManager &mgr, const Teuchos::RCP< Thyra::ProductMultiVectorBase< double > > &blkVec)
Convert a flat multi vector into a reordered multivector.
virtual void SetBlock(int blockIndex, int reorder)
Sets the sublock to a specific index value.
Teuchos::RCP< const BlockReorderManager > blockedReorderFromString(std::string &reorder)
Convert a string to a block reorder manager object.
virtual const Teuchos::RCP< BlockReorderManager > GetBlock(int blockIndex)
Get a particular block. If there is no block at this index location return a new one.
Teuchos::RCP< const Thyra::LinearOpBase< double > > buildReorderedLinearOp(const BlockReorderManager &bmm, const Teuchos::RCP< const Thyra::BlockedLinearOpBase< double > > &blkOp)
Use the BlockReorderManager to change a flat square blocked operator into a composite operator.
virtual int LargestIndex() const
Largest index in this manager.
BlockReorderManager()
Basic empty constructor.
std::vector< Teuchos::RCP< BlockReorderManager > > children_
Definitions of the subblocks.
virtual int GetNumBlocks() const
Gets the number of subblocks.
Teuchos::RCP< const Thyra::VectorSpaceBase< double > > buildReorderedVectorSpace(const BlockReorderManager &mgr, const Teuchos::RCP< const Thyra::ProductVectorSpaceBase< double > > &blkSpc)
Use the BlockReorderManager to change a flat vector space into a composite vector space.
Teuchos::RCP< Thyra::MultiVectorBase< double > > buildFlatMultiVector(const BlockReorderManager &mgr, const Teuchos::RCP< Thyra::ProductMultiVectorBase< double > > &blkVec)
Convert a reordered multivector into a flat multivector.