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"
28 using 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;
101 Teuchos::RCP<const Thyra::LinearOpBase<double> > buildReorderedLinearOp(
103 const Teuchos::RCP<
const Thyra::BlockedLinearOpBase<double> > &blkOp) {
104 return buildReorderedLinearOp(bmm, bmm, blkOp);
107 Teuchos::RCP<const Thyra::LinearOpBase<double> > buildReorderedLinearOp(
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);
140 reBlkOp->setBlock(0, col, buildReorderedLinearOp(rowMgr, *colPtr, blkOp));
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);
157 reBlkOp->setBlock(row, 0, buildReorderedLinearOp(*rowPtr, colMgr, blkOp));
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);
180 reBlkOp->setBlock(row, col, buildReorderedLinearOp(*rowPtr, *colPtr, blkOp));
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 =
233 buildReorderedVectorSpace(*blkMgr, blkSpc);
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);
333 void buildNonconstFlatMultiVector(
const BlockReorderManager &mgr,
334 const RCP<Thyra::MultiVectorBase<double> > &blkVec,
335 Array<RCP<Thyra::MultiVectorBase<double> > > &multivecs,
336 Array<RCP<
const Thyra::VectorSpaceBase<double> > > &vecspaces) {
337 int sz = mgr.GetNumBlocks();
341 const BlockReorderLeaf &leaf =
dynamic_cast<const BlockReorderLeaf &
>(mgr);
342 int index = leaf.GetIndex();
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);
362 void buildFlatMultiVector(
const BlockReorderManager &mgr,
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();
370 const BlockReorderLeaf &leaf =
dynamic_cast<const BlockReorderLeaf &
>(mgr);
371 int index = leaf.GetIndex();
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);
392 Teuchos::RCP<Thyra::MultiVectorBase<double> > buildFlatMultiVector(
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);
415 Teuchos::RCP<const Thyra::MultiVectorBase<double> > buildFlatMultiVector(
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);
424 buildFlatMultiVector(mgr, blkVec, multivecs, vecspaces);
427 const RCP<const Thyra::DefaultProductVectorSpace<double> > vs =
428 Thyra::productVectorSpace<double>(vecspaces);
431 return Thyra::defaultProductMultiVector<double>(vs, multivecs);
437 void buildFlatVectorSpace(
const BlockReorderManager &mgr,
438 const RCP<
const Thyra::VectorSpaceBase<double> > &blkSpc,
439 Array<RCP<
const Thyra::VectorSpaceBase<double> > > &vecspaces) {
440 int sz = mgr.GetNumBlocks();
444 const BlockReorderLeaf &leaf =
dynamic_cast<const BlockReorderLeaf &
>(mgr);
445 int index = leaf.GetIndex();
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);
463 Teuchos::RCP<const Thyra::VectorSpaceBase<double> > buildFlatVectorSpace(
464 const BlockReorderManager &mgr,
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);
484 static 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;
544 static 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());
568 static RCP<BlockReorderManager> blockedReorderFromTokens(
const std::vector<std::string> &tokens) {
570 if (tokens.size() == 1)
574 TEUCHOS_ASSERT(*(tokens.begin()) ==
"[")
575 TEUCHOS_ASSERT(*(tokens.end() - 1) == "]");
577 std::vector<RCP<Teko::BlockReorderManager> > vecRMgr;
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));
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.
std::vector< Teuchos::RCP< BlockReorderManager > > children_
Definitions of the subblocks.
Class that describes how a flat blocked operator should be reordered.
virtual int GetNumBlocks() const
Gets the number of subblocks.
virtual int LargestIndex() const
Largest index in this manager.
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< Thyra::MultiVectorBase< double > > buildReorderedMultiVector(const BlockReorderManager &mgr, const Teuchos::RCP< Thyra::ProductMultiVectorBase< double > > &blkVec)
Convert a flat multi vector into a reordered multivector.
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...
virtual std::string toString() const
For sanities sake, print a readable string.
BlockReorderManager()
Basic empty constructor.
Teuchos::RCP< const BlockReorderManager > blockedReorderFromString(std::string &reorder)
Convert a string to a block reorder manager object.
virtual void SetBlock(int blockIndex, int reorder)
Sets the sublock to a specific index value.