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) {
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) {
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();
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);
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);
362void 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);
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);
392Teuchos::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);
415Teuchos::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);
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(
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);
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)
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);